mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
Prelimilary parsing support of references, payload, inherits and specializes
This commit is contained in:
@@ -121,10 +121,10 @@ static void RegisterStageMetas(
|
||||
std::map<std::string, AsciiParser::VariableDef> &metas) {
|
||||
metas.clear();
|
||||
metas["doc"] = AsciiParser::VariableDef(value::kString, "doc");
|
||||
metas["documentation"] = AsciiParser::VariableDef(value::kString, "doc"); // alias to 'doc'
|
||||
metas["documentation"] =
|
||||
AsciiParser::VariableDef(value::kString, "doc"); // alias to 'doc'
|
||||
|
||||
metas["comment"] =
|
||||
AsciiParser::VariableDef(value::kString, "comment");
|
||||
metas["comment"] = AsciiParser::VariableDef(value::kString, "comment");
|
||||
|
||||
// TODO: both support float and double?
|
||||
metas["metersPerUnit"] =
|
||||
@@ -146,7 +146,8 @@ static void RegisterStageMetas(
|
||||
|
||||
// Composition arc.
|
||||
// Type can be array. i.e. asset, asset[]
|
||||
metas["subLayers"] = AsciiParser::VariableDef(value::kAssetPath, "subLayers", /* allow array type */true);
|
||||
metas["subLayers"] = AsciiParser::VariableDef(value::kAssetPath, "subLayers",
|
||||
/* allow array type */ true);
|
||||
}
|
||||
|
||||
static void RegisterPrimMetas(
|
||||
@@ -156,29 +157,30 @@ static void RegisterPrimMetas(
|
||||
metas["kind"] = AsciiParser::VariableDef(value::kToken, "kind");
|
||||
metas["doc"] = AsciiParser::VariableDef(value::kString, "doc");
|
||||
|
||||
// Composition arcs
|
||||
//
|
||||
// Composition arcs -----------------------
|
||||
//
|
||||
|
||||
// Type can be array. i.e. path, path[]
|
||||
metas["references"] =
|
||||
AsciiParser::VariableDef(value::kAssetPath, "references", /* allow array type */true);
|
||||
metas["references"] = AsciiParser::VariableDef("Reference", "references",
|
||||
/* allow array type */ true);
|
||||
metas["inherits"] = AsciiParser::VariableDef(value::kPath, "inherits", true);
|
||||
metas["payload"] = AsciiParser::VariableDef(value::kAssetPath, "payload", true);
|
||||
|
||||
metas["payload"] = AsciiParser::VariableDef("Reference", "payload", true);
|
||||
metas["specializes"] =
|
||||
AsciiParser::VariableDef(value::kRelationship, "specializes");
|
||||
AsciiParser::VariableDef(value::kPath, "specializes", true);
|
||||
metas["variantSets"] = AsciiParser::VariableDef(value::kToken, "variantSets",
|
||||
/* allow array type */ true);
|
||||
|
||||
// token or token[]
|
||||
metas["variantSets"] =
|
||||
AsciiParser::VariableDef(value::kToken, "variantSets", /* allow array type */true);
|
||||
// Parse as dict. TODO: Use ParseVariants()
|
||||
metas["variants"] = AsciiParser::VariableDef(value::kDictionary, "variants");
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
metas["assetInfo"] =
|
||||
AsciiParser::VariableDef(value::kDictionary, "assetInfo");
|
||||
metas["customData"] =
|
||||
AsciiParser::VariableDef(value::kDictionary, "customData");
|
||||
|
||||
// TODO: Use ParseVariants
|
||||
metas["variants"] = AsciiParser::VariableDef(value::kDictionary, "variants");
|
||||
|
||||
metas["active"] = AsciiParser::VariableDef(value::kBool, "active");
|
||||
|
||||
// usdSkel
|
||||
@@ -755,10 +757,30 @@ bool AsciiParser::ReadBasicType(
|
||||
template <typename T, size_t N>
|
||||
bool AsciiParser::ParseTupleArray(
|
||||
std::vector<nonstd::optional<std::array<T, N>>> *result) {
|
||||
|
||||
if (!Expect('[')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipCommentAndWhitespaceAndNewline()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty array?
|
||||
{
|
||||
char c;
|
||||
if (!Char1(&c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c == ']') {
|
||||
result->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rewind(1);
|
||||
}
|
||||
|
||||
if (!SepBy1TupleType<T, N>(',', result)) {
|
||||
return false;
|
||||
}
|
||||
@@ -815,7 +837,6 @@ bool AsciiParser::ReadBasicType(nonstd::optional<Identifier> *value) {
|
||||
|
||||
template <>
|
||||
bool AsciiParser::ReadBasicType(value::token *value) {
|
||||
|
||||
// Try triple-quotated string first.
|
||||
{
|
||||
StringData sdata;
|
||||
@@ -1834,6 +1855,25 @@ bool AsciiParser::ParseBasicTypeArray(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipCommentAndWhitespaceAndNewline()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty array?
|
||||
{
|
||||
char c;
|
||||
if (!Char1(&c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c == ']') {
|
||||
result->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rewind(1);
|
||||
}
|
||||
|
||||
if (!SepBy1BasicType<T>(',', result)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2058,6 +2098,26 @@ bool AsciiParser::ParseBasicTypeArray(std::vector<Reference> *result) {
|
||||
result->push_back(ref);
|
||||
|
||||
} else {
|
||||
|
||||
if (!SkipCommentAndWhitespaceAndNewline()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty array?
|
||||
{
|
||||
char ce;
|
||||
if (!Char1(&ce)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ce == ']') {
|
||||
result->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rewind(1);
|
||||
}
|
||||
|
||||
if (!SepBy1BasicType(',', result)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2083,6 +2143,25 @@ bool AsciiParser::ParseBasicTypeArray(std::vector<Path> *result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!SkipCommentAndWhitespaceAndNewline()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Empty array?
|
||||
{
|
||||
char c;
|
||||
if (!Char1(&c)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (c == ']') {
|
||||
result->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
Rewind(1);
|
||||
}
|
||||
|
||||
if (!SepBy1BasicType(',', result)) {
|
||||
return false;
|
||||
}
|
||||
@@ -2831,7 +2910,6 @@ bool AsciiParser::ReadBasicType(nonstd::optional<value::quatd> *value) {
|
||||
|
||||
template <>
|
||||
bool AsciiParser::ReadBasicType(value::AssetPath *value) {
|
||||
|
||||
bool triple_deliminated;
|
||||
if (ParseAssetIdentifier(value, &triple_deliminated)) {
|
||||
return true;
|
||||
@@ -2855,6 +2933,33 @@ bool AsciiParser::ReadBasicType(nonstd::optional<value::AssetPath> *value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool AsciiParser::ReadBasicType(Reference *value) {
|
||||
bool triple_deliminated;
|
||||
if (ParseReference(value, &triple_deliminated)) {
|
||||
return true;
|
||||
}
|
||||
(void)triple_deliminated;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool AsciiParser::ReadBasicType(nonstd::optional<Reference> *value) {
|
||||
if (MaybeNone()) {
|
||||
(*value) = nonstd::nullopt;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference v;
|
||||
if (ReadBasicType(&v)) {
|
||||
(*value) = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1D array
|
||||
template <typename T>
|
||||
bool AsciiParser::ReadBasicType(std::vector<T> *value) {
|
||||
@@ -3136,8 +3241,7 @@ bool AsciiParser::ParseDict(std::map<std::string, MetaVariable> *out_dict) {
|
||||
}
|
||||
|
||||
bool AsciiParser::ParseVariantsElement(std::string *out_key,
|
||||
std::string *out_var) {
|
||||
|
||||
std::string *out_var) {
|
||||
// variants_element: string name '=' value
|
||||
// ;
|
||||
|
||||
@@ -3149,7 +3253,8 @@ bool AsciiParser::ParseVariantsElement(std::string *out_key,
|
||||
|
||||
// must be `string`
|
||||
if (type_name != value::kString) {
|
||||
PUSH_ERROR_AND_RETURN("TinyUSDZ only accepts type `string` for `variants` element.");
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"TinyUSDZ only accepts type `string` for `variants` element.");
|
||||
}
|
||||
|
||||
if (!SkipWhitespace()) {
|
||||
@@ -3361,8 +3466,9 @@ bool AsciiParser::ReadStringLiteral(std::string *literal) {
|
||||
}
|
||||
|
||||
if (!end_with_quotation) {
|
||||
PUSH_ERROR_AND_RETURN(fmt::format("String literal expected but it does not end with {}.",
|
||||
single_quote ? "'" : "\""));
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
fmt::format("String literal expected but it does not end with {}.",
|
||||
single_quote ? "'" : "\""));
|
||||
}
|
||||
|
||||
(*literal) = ss.str();
|
||||
@@ -3457,7 +3563,7 @@ bool AsciiParser::MaybeTripleQuotedString(StringData *str) {
|
||||
triple_quote[2] == '"') {
|
||||
// ok
|
||||
} else if (triple_quote[0] == '\'' && triple_quote[1] == '\'' &&
|
||||
triple_quote[2] == '\'') {
|
||||
triple_quote[2] == '\'') {
|
||||
// ok
|
||||
single_quote = true;
|
||||
} else {
|
||||
@@ -3470,8 +3576,8 @@ bool AsciiParser::MaybeTripleQuotedString(StringData *str) {
|
||||
|
||||
auto locinfo = _curr_cursor;
|
||||
|
||||
int single_quote_count = 0; // '
|
||||
int double_quote_count = 0; // "
|
||||
int single_quote_count = 0; // '
|
||||
int double_quote_count = 0; // "
|
||||
|
||||
bool got_triple_quote{false};
|
||||
|
||||
@@ -3551,7 +3657,7 @@ bool AsciiParser::MaybeTripleQuotedString(StringData *str) {
|
||||
// remove last '"""' or '''
|
||||
str->single_quote = single_quote;
|
||||
std::string s = str_buf.str();
|
||||
if (s.size() > 3) { // just in case
|
||||
if (s.size() > 3) { // just in case
|
||||
s.erase(s.size() - 3);
|
||||
}
|
||||
str->value = s;
|
||||
@@ -4601,12 +4707,12 @@ AsciiParser::TryParseTimeSamplesOfArray() {
|
||||
data.push_back({timeVal, tsValue});
|
||||
}
|
||||
|
||||
DCOUT("Parse TimeSamples of array type success. # of items = " << data.size());
|
||||
DCOUT(
|
||||
"Parse TimeSamples of array type success. # of items = " << data.size());
|
||||
|
||||
return std::move(data);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
value::TimeSamples AsciiParser::ConvertToTimeSamples(
|
||||
const TimeSampleData<T> &ts) {
|
||||
@@ -4922,8 +5028,8 @@ bool AsciiParser::ParseCustomMetaValue() {
|
||||
PUSH_ERROR_AND_RETURN("TODO");
|
||||
}
|
||||
|
||||
bool AsciiParser::ParseAssetIdentifier(value::AssetPath *out, bool *triple_deliminated)
|
||||
{
|
||||
bool AsciiParser::ParseAssetIdentifier(value::AssetPath *out,
|
||||
bool *triple_deliminated) {
|
||||
// @...@
|
||||
// or @@@...@@@ (Triple '@'-deliminated asset identifier.)
|
||||
// @@@ = Path containing '@'. '@@@' in Path is encoded as '\@@@'
|
||||
@@ -5058,7 +5164,6 @@ bool AsciiParser::ParseAssetIdentifier(value::AssetPath *out, bool *triple_delim
|
||||
|
||||
// TODO: Return Path
|
||||
bool AsciiParser::ParseReference(Reference *out, bool *triple_deliminated) {
|
||||
|
||||
/*
|
||||
Asset reference = AsssetIdentifier + optially followd by prim path
|
||||
|
||||
@@ -5135,7 +5240,8 @@ bool AsciiParser::ParseMetaValue(const VariableDef &def, MetaVariable *outvar) {
|
||||
if (is_array_type) {
|
||||
std::vector<value::token> value;
|
||||
if (!ParseBasicTypeArray(&value)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, fmt::format("token[] expected for `{}`.", varname));
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, fmt::format("token[] expected for `{}`.", varname));
|
||||
}
|
||||
DCOUT("token[] = " << value);
|
||||
|
||||
@@ -5152,7 +5258,6 @@ bool AsciiParser::ParseMetaValue(const VariableDef &def, MetaVariable *outvar) {
|
||||
var.Set(value);
|
||||
}
|
||||
} else if (vartype == "token[]") {
|
||||
|
||||
std::vector<value::token> value;
|
||||
if (!ParseBasicTypeArray(&value)) {
|
||||
std::string msg = "Token array expected for `" + varname + "`.\n";
|
||||
@@ -5318,33 +5423,63 @@ bool AsciiParser::ParseMetaValue(const VariableDef &def, MetaVariable *outvar) {
|
||||
if (is_array_type) {
|
||||
std::vector<Path> paths;
|
||||
if (!ParseBasicTypeArray(&paths)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, fmt::format("Failed to parse `{}` in Prim metadatum.", def.name));
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadatum.", def.name));
|
||||
}
|
||||
var.Set(paths);
|
||||
|
||||
var.type = vartype + "[]";
|
||||
|
||||
} else {
|
||||
Path path;
|
||||
if (!ReadBasicType(&path)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, fmt::format("Failed to parse `{}` in Prim metadatum.", def.name));
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadatum.", def.name));
|
||||
}
|
||||
}
|
||||
|
||||
var.Set(path);
|
||||
}
|
||||
|
||||
} else if (vartype == value::kAssetPath) {
|
||||
if (is_array_type) {
|
||||
std::vector<value::AssetPath> paths;
|
||||
if (!ParseBasicTypeArray(&paths)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
}
|
||||
var.Set(paths);
|
||||
} else {
|
||||
value::AssetPath asset_path;
|
||||
if (!ReadBasicType(&asset_path)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
}
|
||||
var.Set(asset_path);
|
||||
}
|
||||
|
||||
} else if (vartype == "Reference") {
|
||||
if (is_array_type) {
|
||||
std::vector<Reference> refs;
|
||||
if (!ParseBasicTypeArray(&refs)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
}
|
||||
var.Set(refs);
|
||||
} else {
|
||||
nonstd::optional<Reference> ref;
|
||||
if (!ReadBasicType(&ref)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii,
|
||||
fmt::format("Failed to parse `{}` in Prim metadataum.", def.name));
|
||||
}
|
||||
if (ref) {
|
||||
var.Set(ref.value());
|
||||
} else {
|
||||
// None
|
||||
var.Set(value::ValueBlock());
|
||||
}
|
||||
}
|
||||
} else if (vartype == value::kDictionary) {
|
||||
DCOUT("Parse dict in meta.");
|
||||
CustomDataType dict;
|
||||
@@ -6230,7 +6365,8 @@ bool AsciiParser::ParsePrimProps(std::map<std::string, Property> *props) {
|
||||
//
|
||||
|
||||
if (listop_qual != ListEditQual::ResetToExplicit) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, "List editing qualifier is not allowed for Attribute.");
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, "List editing qualifier is not allowed for Attribute.");
|
||||
}
|
||||
|
||||
if (type_name == "uniform") {
|
||||
@@ -6363,7 +6499,7 @@ bool AsciiParser::ParsePrimProps(std::map<std::string, Property> *props) {
|
||||
Relation rel;
|
||||
rel.Set(path);
|
||||
|
||||
Property p(rel, /* value typename */type_name, custom_qual);
|
||||
Property p(rel, /* value typename */ type_name, custom_qual);
|
||||
|
||||
(*props)[primattr_name] = p;
|
||||
|
||||
@@ -6382,23 +6518,22 @@ bool AsciiParser::ParsePrimProps(std::map<std::string, Property> *props) {
|
||||
}
|
||||
|
||||
// 1D and scalar
|
||||
#define PARSE_TYPE(__type) \
|
||||
if ((type_name == value::TypeTrait<__type>::type_name()) && array_qual) { \
|
||||
if (auto pv = TryParseTimeSamplesOfArray<__type>()) { \
|
||||
ts = ConvertToTimeSamples<std::vector<__type>>(pv.value()); \
|
||||
} else { \
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
|
||||
<< value::TypeTrait<__type>::type_name() \
|
||||
<< "[]`"); \
|
||||
} \
|
||||
} else if (type_name == value::TypeTrait<__type>::type_name()) { \
|
||||
if (auto pv = TryParseTimeSamples<__type>()) { \
|
||||
ts = ConvertToTimeSamples<__type>(pv.value()); \
|
||||
} else { \
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
|
||||
<< value::TypeTrait<__type>::type_name() \
|
||||
<< "`"); \
|
||||
} \
|
||||
#define PARSE_TYPE(__type) \
|
||||
if ((type_name == value::TypeTrait<__type>::type_name()) && array_qual) { \
|
||||
if (auto pv = TryParseTimeSamplesOfArray<__type>()) { \
|
||||
ts = ConvertToTimeSamples<std::vector<__type>>(pv.value()); \
|
||||
} else { \
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
|
||||
<< value::TypeTrait<__type>::type_name() \
|
||||
<< "[]`"); \
|
||||
} \
|
||||
} else if (type_name == value::TypeTrait<__type>::type_name()) { \
|
||||
if (auto pv = TryParseTimeSamples<__type>()) { \
|
||||
ts = ConvertToTimeSamples<__type>(pv.value()); \
|
||||
} else { \
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse timeSample data with type `" \
|
||||
<< value::TypeTrait<__type>::type_name() << "`"); \
|
||||
} \
|
||||
} else
|
||||
|
||||
value::TimeSamples ts;
|
||||
@@ -6463,7 +6598,8 @@ bool AsciiParser::ParsePrimProps(std::map<std::string, Property> *props) {
|
||||
} else {
|
||||
PrimAttrib attr;
|
||||
|
||||
// TODO: Refactor. ParseAttrMeta is currently called inside ParseBasicPrimAttr()
|
||||
// TODO: Refactor. ParseAttrMeta is currently called inside
|
||||
// ParseBasicPrimAttr()
|
||||
if (type_name == value::kBool) {
|
||||
if (!ParseBasicPrimAttr<bool>(array_qual, primattr_name, &attr)) {
|
||||
return false;
|
||||
@@ -6722,7 +6858,7 @@ bool AsciiParser::IsStageMeta(const std::string &name) {
|
||||
return _supported_stage_metas.count(name) ? true : false;
|
||||
}
|
||||
|
||||
#if 0 // TODO: Remove
|
||||
#if 0 // TODO: Remove
|
||||
///
|
||||
/// Parse `class` block.
|
||||
///
|
||||
@@ -6917,8 +7053,8 @@ bool AsciiParser::ParseOverBlock(const int64_t primIdx,
|
||||
#endif
|
||||
|
||||
bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
const int64_t parentPrimIdx,
|
||||
const uint32_t depth) {
|
||||
const int64_t parentPrimIdx,
|
||||
const uint32_t depth) {
|
||||
// {
|
||||
// "variantName0" { ... }
|
||||
// "variantName1" { ... }
|
||||
@@ -6932,7 +7068,6 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (!Eof()) {
|
||||
{
|
||||
char c;
|
||||
@@ -6951,7 +7086,8 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
// string
|
||||
std::string variantName;
|
||||
if (!ReadBasicType(&variantName)) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, "Failed to parse variant name for `variantSet` statement.");
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, "Failed to parse variant name for `variantSet` statement.");
|
||||
}
|
||||
|
||||
if (!SkipWhitespace()) {
|
||||
@@ -6969,7 +7105,6 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
}
|
||||
|
||||
while (!Eof()) {
|
||||
|
||||
{
|
||||
char c;
|
||||
if (!Char1(&c)) {
|
||||
@@ -6999,8 +7134,7 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
}
|
||||
|
||||
if (tok == "variantSet") {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"Nested `variantSet` is not supported yet.");
|
||||
PUSH_ERROR_AND_RETURN("Nested `variantSet` is not supported yet.");
|
||||
}
|
||||
|
||||
Specifier child_spec{Specifier::Invalid};
|
||||
@@ -7015,11 +7149,13 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
if (child_spec != Specifier::Invalid) {
|
||||
// FIXME: Prim index stacking.
|
||||
int64_t idx = _prim_idx_assign_fun(parentPrimIdx);
|
||||
DCOUT("enter parseDef. spec = " << to_string(child_spec) << ", idx = " << idx << ", rootIdx = " << primIdx);
|
||||
DCOUT("enter parseDef. spec = " << to_string(child_spec) << ", idx = "
|
||||
<< idx << ", rootIdx = " << primIdx);
|
||||
|
||||
// recusive call
|
||||
if (!ParseBlock(child_spec, idx, primIdx, depth + 1)) {
|
||||
PUSH_ERROR_AND_RETURN(fmt::format("`{}` block parse failed.", to_string(child_spec)));
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
fmt::format("`{}` block parse failed.", to_string(child_spec)));
|
||||
}
|
||||
DCOUT(fmt::format("Done parse `{}` block.", to_string(child_spec)));
|
||||
} else {
|
||||
@@ -7041,8 +7177,7 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
}
|
||||
|
||||
DCOUT("variantSet item parsed.");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -7059,8 +7194,8 @@ bool AsciiParser::ParseVariantSet(const int64_t primIdx,
|
||||
/// another USD file or referenced USD)
|
||||
///
|
||||
bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
const int64_t parentPrimIdx,
|
||||
const uint32_t depth) {
|
||||
const int64_t parentPrimIdx,
|
||||
const uint32_t depth) {
|
||||
DCOUT("ParseBlock");
|
||||
|
||||
if (!SkipCommentAndWhitespaceAndNewline()) {
|
||||
@@ -7084,17 +7219,20 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
// Ensure spec and def is same.
|
||||
if (def == "def") {
|
||||
if (spec != Specifier::Def) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
}
|
||||
}
|
||||
if (def == "over") {
|
||||
if (spec != Specifier::Over) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
}
|
||||
}
|
||||
if (def == "class") {
|
||||
if (spec != Specifier::Class) {
|
||||
PUSH_ERROR_AND_RETURN_TAG(kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
PUSH_ERROR_AND_RETURN_TAG(
|
||||
kAscii, "Internal error. Invalid Specifier token combination.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7192,15 +7330,25 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::pair<ListEditQual, Reference>> references;
|
||||
#if 0
|
||||
std::pair<ListEditQual, std::vector<Reference>> references;
|
||||
std::pair<ListEditQual, std::vector<Reference>> payload;
|
||||
DCOUT("`references.count` = " + std::to_string(in_metas.count("references")));
|
||||
|
||||
// TODO
|
||||
if (in_metas.count("references")) {
|
||||
// TODO
|
||||
// references = GetReferences(args["references"]);
|
||||
// DCOUT("`references.size` = " + std::to_string(references.size()));
|
||||
}
|
||||
|
||||
// TODO
|
||||
if (in_metas.count("payload")) {
|
||||
// TODO
|
||||
// payload = GetReferences(args["payload"]);
|
||||
// DCOUT("`payload.size` = " + std::to_string(payload.size()));
|
||||
}
|
||||
#endif
|
||||
|
||||
std::map<std::string, Property> props;
|
||||
|
||||
@@ -7258,8 +7406,7 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
|
||||
std::string variantName;
|
||||
if (!ReadBasicType(&variantName)) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"Failed to parse `variantSet` statement.");
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse `variantSet` statement.");
|
||||
}
|
||||
|
||||
DCOUT("variantName = " << variantName);
|
||||
@@ -7277,8 +7424,7 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
}
|
||||
|
||||
if (!ParseVariantSet(primIdx, parentPrimIdx, depth)) {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"Failed to parse `variantSet` statement.");
|
||||
PUSH_ERROR_AND_RETURN("Failed to parse `variantSet` statement.");
|
||||
}
|
||||
|
||||
continue;
|
||||
@@ -7288,7 +7434,6 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Specifier child_spec{Specifier::Invalid};
|
||||
if (tok == "def") {
|
||||
child_spec = Specifier::Def;
|
||||
@@ -7300,11 +7445,13 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
|
||||
if (child_spec != Specifier::Invalid) {
|
||||
int64_t idx = _prim_idx_assign_fun(parentPrimIdx);
|
||||
DCOUT("enter parseDef. spec = " << to_string(child_spec) << ", idx = " << idx << ", rootIdx = " << primIdx);
|
||||
DCOUT("enter parseDef. spec = " << to_string(child_spec) << ", idx = "
|
||||
<< idx << ", rootIdx = " << primIdx);
|
||||
|
||||
// recusive call
|
||||
if (!ParseBlock(child_spec, idx, primIdx, depth + 1)) {
|
||||
PUSH_ERROR_AND_RETURN(fmt::format("`{}` block parse failed.", to_string(child_spec)));
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
fmt::format("`{}` block parse failed.", to_string(child_spec)));
|
||||
}
|
||||
DCOUT(fmt::format("Done parse `{}` block.", to_string(child_spec)));
|
||||
} else {
|
||||
@@ -7325,10 +7472,8 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
|
||||
if (prim_type.empty()) {
|
||||
// No Prim type specified. Treat it as Model
|
||||
// TODO: support `references` and infer prim type from referenced asset.
|
||||
|
||||
pTy = "Model";
|
||||
|
||||
}
|
||||
|
||||
if (_prim_construct_fun_map.count(pTy)) {
|
||||
@@ -7337,7 +7482,7 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
Path fullpath(GetCurrentPath(), "");
|
||||
Path pname(prim_name, "");
|
||||
nonstd::expected<bool, std::string> ret = construct_fun(
|
||||
fullpath, spec, pname, primIdx, parentPrimIdx, props, references, in_metas);
|
||||
fullpath, spec, pname, primIdx, parentPrimIdx, props, in_metas);
|
||||
|
||||
if (!ret) {
|
||||
// construction failed.
|
||||
@@ -7345,7 +7490,9 @@ bool AsciiParser::ParseBlock(const Specifier spec, const int64_t primIdx,
|
||||
"` failed: " + ret.error());
|
||||
}
|
||||
} else {
|
||||
PUSH_WARN(fmt::format("TODO: Unsupported/Unimplemented Prim type: `{}`. Skipping parsing.", pTy));
|
||||
PUSH_WARN(fmt::format(
|
||||
"TODO: Unsupported/Unimplemented Prim type: `{}`. Skipping parsing.",
|
||||
pTy));
|
||||
}
|
||||
|
||||
PopPath();
|
||||
|
||||
@@ -246,7 +246,7 @@ class AsciiParser {
|
||||
std::function<nonstd::expected<bool, std::string>(
|
||||
const Path &full_path, const Specifier spec, const Path &prim_name, const int64_t primIdx, const int64_t parentPrimIdx,
|
||||
const std::map<std::string, Property> &properties,
|
||||
std::vector<std::pair<ListEditQual, Reference>> &references, const PrimMetaInput &in_meta)>;
|
||||
const PrimMetaInput &in_meta)>;
|
||||
|
||||
///
|
||||
/// Register Prim construction callback function.
|
||||
|
||||
112
src/pprinter.cc
112
src/pprinter.cc
@@ -4,6 +4,7 @@
|
||||
//
|
||||
#include "pprinter.hh"
|
||||
#include "prim-types.hh"
|
||||
#include "prim-pprint.hh"
|
||||
#include "usdShade.hh"
|
||||
#include "value-pprint.hh"
|
||||
#include "str-util.hh"
|
||||
@@ -39,6 +40,26 @@ std::ostream &operator<<(std::ostream &ofs, const tinyusdz::Path &v) {
|
||||
return ofs;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &ofs, const tinyusdz::Reference &v) {
|
||||
|
||||
ofs << v.asset_path;
|
||||
if (v.prim_path.IsValid()) {
|
||||
ofs << v.prim_path;
|
||||
}
|
||||
|
||||
return ofs;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &ofs, const tinyusdz::Payload &v) {
|
||||
|
||||
ofs << v.asset_path;
|
||||
if (v._prim_path.IsValid()) {
|
||||
ofs << v._prim_path;
|
||||
}
|
||||
|
||||
return ofs;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &ofs, const tinyusdz::StringData &v) {
|
||||
|
||||
std::string delim = v.single_quote ? "'" : "\"";
|
||||
@@ -93,14 +114,6 @@ void SetIndentString(const std::string &s) {
|
||||
namespace {
|
||||
|
||||
|
||||
#if 0
|
||||
// TODO: Triple @
|
||||
std::string aquote(const value::AssetPath &p) {
|
||||
return wquote(p.GetAssetPath(), "@", "@");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
std::string to_string(const double &v) {
|
||||
std::stringstream ss;
|
||||
ss << v;
|
||||
@@ -232,6 +245,53 @@ std::string print_variantsMap(const VariantsMap &m, const uint32_t indent) {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string print_references(const prim::ReferenceList &references, const uint32_t indent) {
|
||||
std::stringstream ss;
|
||||
|
||||
auto listEditQual = std::get<0>(references);
|
||||
auto vars = std::get<1>(references);
|
||||
|
||||
ss << pprint::Indent(indent);
|
||||
|
||||
if (listEditQual != ListEditQual::ResetToExplicit) {
|
||||
ss << to_string(listEditQual) << " ";
|
||||
}
|
||||
|
||||
ss << "references = ";
|
||||
|
||||
if (vars.empty()) {
|
||||
ss << "None";
|
||||
} else {
|
||||
ss << vars;
|
||||
}
|
||||
ss << "\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string print_payload(const prim::PayloadList &payload, const uint32_t indent) {
|
||||
std::stringstream ss;
|
||||
|
||||
auto listEditQual = std::get<0>(payload);
|
||||
auto vars = std::get<1>(payload);
|
||||
|
||||
ss << pprint::Indent(indent);
|
||||
|
||||
if (listEditQual != ListEditQual::ResetToExplicit) {
|
||||
ss << to_string(listEditQual) << " ";
|
||||
}
|
||||
|
||||
ss << "payload = ";
|
||||
if (vars.empty()) {
|
||||
ss << "None";
|
||||
} else {
|
||||
ss << vars;
|
||||
}
|
||||
ss << "\n";
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string print_prim_metas(const PrimMeta &meta, const uint32_t indent) {
|
||||
|
||||
std::stringstream ss;
|
||||
@@ -248,6 +308,40 @@ std::string print_prim_metas(const PrimMeta &meta, const uint32_t indent) {
|
||||
ss << print_customData(meta.assetInfo.value(), "assetInfo", indent);
|
||||
}
|
||||
|
||||
if (meta.inherits) {
|
||||
ss << pprint::Indent(indent);
|
||||
auto listEditQual = std::get<0>(meta.inherits.value());
|
||||
auto var = std::get<1>(meta.inherits.value());
|
||||
|
||||
if (listEditQual != ListEditQual::ResetToExplicit) {
|
||||
ss << to_string(listEditQual) << " ";
|
||||
}
|
||||
|
||||
ss << "inherits = " << var;
|
||||
ss << "\n";
|
||||
}
|
||||
|
||||
if (meta.specializes) {
|
||||
ss << pprint::Indent(indent);
|
||||
auto listEditQual = std::get<0>(meta.specializes.value());
|
||||
auto var = std::get<1>(meta.specializes.value());
|
||||
|
||||
if (listEditQual != ListEditQual::ResetToExplicit) {
|
||||
ss << to_string(listEditQual) << " ";
|
||||
}
|
||||
|
||||
ss << "specializes = " << var;
|
||||
ss << "\n";
|
||||
}
|
||||
|
||||
if (meta.references) {
|
||||
ss << print_references(meta.references.value(), indent);
|
||||
}
|
||||
|
||||
if (meta.payload) {
|
||||
ss << print_payload(meta.payload.value(), indent);
|
||||
}
|
||||
|
||||
if (meta.variants) {
|
||||
ss << print_variantsMap(meta.variants.value(), indent);
|
||||
}
|
||||
@@ -271,7 +365,7 @@ std::string print_prim_metas(const PrimMeta &meta, const uint32_t indent) {
|
||||
ss << "[InternalError]";
|
||||
}
|
||||
|
||||
ss << "\n";
|
||||
ss << "\n";
|
||||
}
|
||||
|
||||
if (meta.apiSchemas) {
|
||||
|
||||
@@ -151,6 +151,7 @@ std::string print_customData(const CustomDataType &customData, const std::string
|
||||
std::string print_variantsMap(const VariantsMap &map, const uint32_t indent);
|
||||
|
||||
|
||||
|
||||
} // namespace tinyusdz
|
||||
|
||||
namespace std {
|
||||
|
||||
21
src/prim-pprint.hh
Normal file
21
src/prim-pprint.hh
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright 2022 - Present, Syoyo Fujita.
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
#include "prim-types.hh"
|
||||
|
||||
namespace tinyusdz {
|
||||
namespace prim {
|
||||
|
||||
//
|
||||
// Impelemnted in pprinter.cc
|
||||
//
|
||||
std::string print_references(const ReferenceList &references, const uint32_t indent);
|
||||
std::string print_payload(const PayloadList &payload, const uint32_t indent);
|
||||
|
||||
|
||||
} // namespace prim
|
||||
} // namespace tinyusdz
|
||||
@@ -1915,15 +1915,19 @@ bool ReconstructPrim(
|
||||
std::string *warn,
|
||||
std::string *err) {
|
||||
|
||||
(void)references;
|
||||
(void)warn;
|
||||
|
||||
#if 0 // TODO
|
||||
//
|
||||
// Resolve prepend references
|
||||
//
|
||||
for (const auto &ref : references) {
|
||||
if (std::get<0>(ref) == tinyusdz::ListEditQual::Prepend) {
|
||||
if (std::get<0>(references) == ListEditQual::Prepend) {
|
||||
for (const auto &ref : std::get<1>(references)) {
|
||||
(void)ref;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
std::set<std::string> table;
|
||||
if (!prim::ReconstructXformOpsFromProperties(table, properties, &xform->xformOps, err)) {
|
||||
@@ -1935,14 +1939,17 @@ bool ReconstructPrim(
|
||||
PARSE_PROPERTY_END_MAKE_WARN(table, prop)
|
||||
}
|
||||
|
||||
#if 0 // TODO
|
||||
//
|
||||
// Resolve append references
|
||||
// (Overwrite variables with the referenced one).
|
||||
//
|
||||
for (const auto &ref : references) {
|
||||
if (std::get<0>(ref) == tinyusdz::ListEditQual::Append) {
|
||||
if (std::get<0>(references) == ListEditQual::Append) {
|
||||
for (const auto &ref : std::get<1>(references)) {
|
||||
(void)ref;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2951,6 +2958,7 @@ bool ReconstructPrim<GeomMesh>(
|
||||
PARSE_PROPERTY_END_MAKE_WARN(table, prop)
|
||||
}
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Resolve append references
|
||||
// (Overwrite variables with the referenced one).
|
||||
@@ -2960,6 +2968,7 @@ bool ReconstructPrim<GeomMesh>(
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,6 @@
|
||||
namespace tinyusdz {
|
||||
namespace prim {
|
||||
|
||||
using PropertyMap = std::map<std::string, Property>;
|
||||
using ReferenceList = std::vector<std::pair<ListEditQual, Reference>>;
|
||||
|
||||
|
||||
///
|
||||
/// Reconstruct property with `xformOp:***` namespace in `properties` to `XformOp` class.
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace tinyusdz {
|
||||
// SpecType enum must be same order with pxrUSD's SdfSpecType(since enum value is stored in Crate directly)
|
||||
enum class SpecType {
|
||||
Unknown = 0, // must be 0
|
||||
Attribute,
|
||||
Attribute,
|
||||
Connection,
|
||||
Expression,
|
||||
Mapper,
|
||||
@@ -354,6 +354,7 @@ class TokenizedPath {
|
||||
|
||||
bool operator==(const Path &lhs, const Path &rhs);
|
||||
|
||||
|
||||
// variants in Prim Meta.
|
||||
//
|
||||
// e.g.
|
||||
@@ -361,7 +362,7 @@ bool operator==(const Path &lhs, const Path &rhs);
|
||||
// string variant0 = "bora"
|
||||
// string variant1 = "dora"
|
||||
// }
|
||||
// pxrUSD uses dict type for the content, but TinyUSDZ only accepts list of strings for now
|
||||
// pxrUSD uses dict type for the content, but TinyUSDZ only accepts list of strings for now
|
||||
//
|
||||
using VariantsMap = std::map<std::string, std::string>;
|
||||
|
||||
@@ -373,7 +374,7 @@ using CustomDataType = std::map<std::string, MetaVariable>;
|
||||
// TODO: Use unify with PrimVar?
|
||||
class MetaVariable {
|
||||
public:
|
||||
std::string type; // Explicit name of type
|
||||
std::string type; // Explicit (declared) name of type
|
||||
std::string name;
|
||||
bool custom{false};
|
||||
|
||||
@@ -432,6 +433,10 @@ class MetaVariable {
|
||||
return type_id(*this);
|
||||
}
|
||||
|
||||
bool IsBlocked() const {
|
||||
return (TypeId() == value::TYPE_ID_VALUEBLOCK);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static std::string type_name(const MetaVariable &v) {
|
||||
@@ -545,6 +550,25 @@ struct APISchemas
|
||||
std::vector<std::pair<APIName, std::string>> names;
|
||||
};
|
||||
|
||||
struct LayerOffset {
|
||||
double _offset;
|
||||
double _scale;
|
||||
};
|
||||
|
||||
struct Payload {
|
||||
value::AssetPath asset_path;
|
||||
Path _prim_path;
|
||||
LayerOffset _layer_offset;
|
||||
};
|
||||
|
||||
struct Reference {
|
||||
value::AssetPath asset_path;
|
||||
Path prim_path;
|
||||
LayerOffset layerOffset;
|
||||
//value::dict custom_data;
|
||||
CustomDataType customData;
|
||||
};
|
||||
|
||||
// Metadata for Prim
|
||||
struct PrimMeta {
|
||||
nonstd::optional<bool> active; // 'active'
|
||||
@@ -554,12 +578,21 @@ struct PrimMeta {
|
||||
nonstd::optional<StringData> doc; // 'documentation'
|
||||
nonstd::optional<StringData> comment; // 'comment'
|
||||
nonstd::optional<APISchemas> apiSchemas; // 'apiSchemas'
|
||||
|
||||
//
|
||||
// Compositions
|
||||
//
|
||||
nonstd::optional<std::pair<ListEditQual, std::vector<Reference>>> references;
|
||||
nonstd::optional<std::pair<ListEditQual, std::vector<Payload>>> payload;
|
||||
// Currently TinyUSDZ allow single Path
|
||||
nonstd::optional<std::pair<ListEditQual, Path>> inherits; // 'inherits'
|
||||
nonstd::optional<std::pair<ListEditQual, MetaVariable>> variantSets; // 'variantSets'. type `token` or `token[]`
|
||||
|
||||
nonstd::optional<VariantsMap> variants; // `variants`
|
||||
|
||||
// Currently TinyUSDZ allow single Path
|
||||
nonstd::optional<std::pair<ListEditQual, Path>> inherits; // 'inherits'
|
||||
nonstd::optional<std::pair<ListEditQual, Path>> specializes; // 'specializes'
|
||||
|
||||
|
||||
// USDZ extensions
|
||||
nonstd::optional<std::string> sceneName; // 'sceneName'
|
||||
@@ -863,7 +896,7 @@ class TypedAttribute {
|
||||
|
||||
return nonstd::nullopt;
|
||||
}
|
||||
|
||||
|
||||
void SetValueEmpty() {
|
||||
_empty = true;
|
||||
}
|
||||
@@ -1193,26 +1226,6 @@ struct ListOpHeader {
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LayerOffset {
|
||||
double _offset;
|
||||
double _scale;
|
||||
};
|
||||
|
||||
struct Payload {
|
||||
std::string _asset_path;
|
||||
Path _prim_path;
|
||||
LayerOffset _layer_offset;
|
||||
};
|
||||
|
||||
struct Reference {
|
||||
value::AssetPath asset_path;
|
||||
Path prim_path;
|
||||
LayerOffset layerOffset;
|
||||
//value::dict custom_data;
|
||||
CustomDataType customData;
|
||||
};
|
||||
|
||||
//
|
||||
// Colum-major order(e.g. employed in OpenGL).
|
||||
// For example, 12th([3][0]), 13th([3][1]), 14th([3][2]) element corresponds to
|
||||
@@ -1610,7 +1623,7 @@ class Property {
|
||||
void SetListEditQual(ListEditQual qual) {
|
||||
_listOpQual = qual;
|
||||
}
|
||||
|
||||
|
||||
const PrimAttrib &GetAttrib() const {
|
||||
return _attrib;
|
||||
}
|
||||
@@ -1635,13 +1648,13 @@ class Property {
|
||||
ListEditQual GetListEditQual() const {
|
||||
return _listOpQual;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
PrimAttrib _attrib;
|
||||
|
||||
// List Edit qualifier(Attribute can never be list editable)
|
||||
// TODO: Store listEdit qualifier to `Relation`
|
||||
ListEditQual _listOpQual{ListEditQual::ResetToExplicit};
|
||||
ListEditQual _listOpQual{ListEditQual::ResetToExplicit};
|
||||
|
||||
Type _type{Type::EmptyAttrib};
|
||||
Relation _rel; // Relation(`rel`) or Connection(`.connect`)
|
||||
@@ -1829,7 +1842,8 @@ struct Model {
|
||||
|
||||
PrimMeta meta;
|
||||
|
||||
std::vector<std::pair<ListEditQual, Reference>> references;
|
||||
std::pair<ListEditQual, std::vector<Reference>> references;
|
||||
std::pair<ListEditQual, std::vector<Payload>> payload;
|
||||
|
||||
std::map<std::string, Property> props;
|
||||
};
|
||||
@@ -2104,6 +2118,15 @@ DEFINE_TYPE_TRAIT(Extent, "float3[]", TYPE_ID_EXTENT, 2); // float3[2]
|
||||
|
||||
} // namespace value
|
||||
|
||||
namespace prim {
|
||||
|
||||
using PropertyMap = std::map<std::string, Property>;
|
||||
using ReferenceList = std::pair<ListEditQual, std::vector<Reference>>;
|
||||
using PayloadList = std::pair<ListEditQual, std::vector<Payload>>;
|
||||
|
||||
} // namespace prim
|
||||
|
||||
|
||||
// TODO(syoyo): Range, Interval, Rect2i, Frustum, MultiInterval
|
||||
// and Quaternion?
|
||||
|
||||
|
||||
@@ -204,8 +204,6 @@ class VariableDef {
|
||||
|
||||
namespace {
|
||||
|
||||
using ReferenceList = std::vector<std::pair<ListEditQual, Reference>>;
|
||||
|
||||
#if 0
|
||||
// Extract array of References from Variable.
|
||||
ReferenceList GetReferences(
|
||||
@@ -461,7 +459,7 @@ class USDAReader::Impl {
|
||||
template <typename T>
|
||||
bool ReconstructPrim(
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const prim::ReferenceList &references,
|
||||
T *out);
|
||||
|
||||
#if 0
|
||||
@@ -484,7 +482,6 @@ class USDAReader::Impl {
|
||||
[&](const Path &full_path, const Specifier spec, const Path &prim_name, const int64_t primIdx,
|
||||
const int64_t parentPrimIdx,
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const ascii::AsciiParser::PrimMetaInput &in_meta)
|
||||
-> nonstd::expected<bool, std::string> {
|
||||
if (!prim_name.IsValid()) {
|
||||
@@ -526,6 +523,11 @@ class USDAReader::Impl {
|
||||
DCOUT("full_path = " << full_path.full_path_name());
|
||||
DCOUT("primName = " << prim_name.full_path_name());
|
||||
|
||||
prim::ReferenceList references;
|
||||
if (prim.meta.references) {
|
||||
references = prim.meta.references.value();
|
||||
}
|
||||
|
||||
bool ret = ReconstructPrim<T>(properties, references, &prim);
|
||||
|
||||
if (!ret) {
|
||||
@@ -663,12 +665,12 @@ class USDAReader::Impl {
|
||||
for (const auto &item : dict) {
|
||||
// TODO: duplicated key check?
|
||||
if (auto pv = item.second.Get<std::string>()) {
|
||||
m[item.first] = pv.value();
|
||||
m[item.first] = pv.value();
|
||||
} else if (auto pvs = item.second.Get<StringData>()) {
|
||||
// TODO: store triple-quote info
|
||||
m[item.first] = pvs.value().value;
|
||||
m[item.first] = pvs.value().value;
|
||||
} else {
|
||||
return nonstd::make_unexpected(fmt::format("TinyUSDZ only accepts `string` value for `variants` element, but got type `{}`(type_id {}).", item.second.TypeName(), item.second.TypeId()));
|
||||
return nonstd::make_unexpected(fmt::format("TinyUSDZ only accepts `string` value for `variants` element, but got type `{}`(type_id {}).", item.second.TypeName(), item.second.TypeId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -800,8 +802,27 @@ class USDAReader::Impl {
|
||||
"got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else if (meta.first == "specializes") {
|
||||
if (auto pv = var.Get<std::vector<Path>>()) {
|
||||
if (pv.value().size() == 0) {
|
||||
// empty
|
||||
} else {
|
||||
// Currently no multiple inherits? are supported.
|
||||
if (pv.value().size() > 1) {
|
||||
PUSH_WARN("Multiple paths are not supported for `specializes`. Use the first one.");
|
||||
}
|
||||
out->specializes = std::make_pair(listEditQual, pv.value()[0]);
|
||||
}
|
||||
} else if (auto pvp = var.Get<Path>()) {
|
||||
out->specializes = std::make_pair(listEditQual, pvp.value());
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"(Internal error?) `specializes` metadataum should be either `path` or `path[]`. "
|
||||
"got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
|
||||
} else if (meta.first == "variantSets") {
|
||||
if (auto pv = var.Get<value::token>()) {
|
||||
out->variantSets = meta.second;
|
||||
@@ -813,7 +834,7 @@ class USDAReader::Impl {
|
||||
"`token` or `token[]`. got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
|
||||
|
||||
} else if (meta.first == "apiSchemas") {
|
||||
DCOUT("apiSchemas. type = " << var.type);
|
||||
if (var.type == "token[]") {
|
||||
@@ -846,6 +867,54 @@ class USDAReader::Impl {
|
||||
"`token[]`. got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
} else if (meta.first == "references") {
|
||||
|
||||
if (var.IsBlocked()) {
|
||||
// create references with empty array.
|
||||
out->references = std::make_pair(listEditQual, std::vector<Reference>());
|
||||
} else if (auto pv = var.Get<Reference>()) {
|
||||
// To Reference
|
||||
std::vector<Reference> refs;
|
||||
refs.emplace_back(pv.value());
|
||||
out->references = std::make_pair(listEditQual, refs);
|
||||
} else if (auto pva = var.Get<std::vector<Reference>>()) {
|
||||
out->references = std::make_pair(listEditQual, pva.value());
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"(Internal error?) `references` metadataum is not type "
|
||||
"`path` or `path[]`. got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
} else if (meta.first == "payload") {
|
||||
|
||||
if (var.IsBlocked()) {
|
||||
// create payload with empty array.
|
||||
out->payload = std::make_pair(listEditQual, std::vector<Payload>());
|
||||
} else if (auto pv = var.Get<Reference>()) {
|
||||
// To Payload
|
||||
std::vector<Payload> refs;
|
||||
Payload ref;
|
||||
ref.asset_path = pv.value().asset_path;
|
||||
ref._prim_path = pv.value().prim_path;
|
||||
// TODO: Other member variables
|
||||
refs.emplace_back(ref);
|
||||
out->payload = std::make_pair(listEditQual, refs);
|
||||
} else if (auto pva = var.Get<std::vector<Reference>>()) {
|
||||
std::vector<Payload> refs;
|
||||
for (const auto &item : pva.value()) {
|
||||
Payload ref;
|
||||
ref.asset_path = item.asset_path;
|
||||
ref._prim_path = item.prim_path;
|
||||
// TODO: Other member variables
|
||||
refs.emplace_back(ref);
|
||||
}
|
||||
out->payload = std::make_pair(listEditQual, refs);
|
||||
} else {
|
||||
PUSH_ERROR_AND_RETURN(
|
||||
"(Internal error?) `references` metadataum is not type "
|
||||
"`path` or `path[]`. got type `"
|
||||
<< var.type << "`");
|
||||
}
|
||||
} else {
|
||||
// string-only data?
|
||||
if (auto pv = var.Get<StringData>()) {
|
||||
@@ -1032,7 +1101,7 @@ bool USDAReader::Impl::ReconstructStage() {
|
||||
template <>
|
||||
bool USDAReader::Impl::ReconstructPrim(
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const prim::ReferenceList &references,
|
||||
Xform *xform) {
|
||||
|
||||
std::string err;
|
||||
@@ -1095,7 +1164,7 @@ bool USDAReader::Impl::RegisterReconstructCallback<GeomSubset>() {
|
||||
[&](const Path &full_path, const Specifier spec, const Path &prim_name, const int64_t primIdx,
|
||||
const int64_t parentPrimIdx,
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
//const prim::ReferenceList &references,
|
||||
const ascii::AsciiParser::PrimMetaInput &in_meta)
|
||||
-> nonstd::expected<bool, std::string> {
|
||||
const Path &parent = full_path.GetParentPrim();
|
||||
@@ -1334,7 +1403,7 @@ bool USDAReader::Impl::RegisterReconstructCallback<GeomSubset>() {
|
||||
template <>
|
||||
bool USDAReader::Impl::ReconstructPrim(
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const prim::ReferenceList &references,
|
||||
GPrim *gprim) {
|
||||
(void)gprim;
|
||||
|
||||
@@ -1349,7 +1418,7 @@ bool USDAReader::Impl::ReconstructPrim(
|
||||
template <>
|
||||
bool USDAReader::Impl::ReconstructPrim<NodeGraph>(
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const prim::ReferenceList &references,
|
||||
NodeGraph *graph) {
|
||||
(void)properties;
|
||||
(void)references;
|
||||
@@ -1380,7 +1449,7 @@ bool USDAReader::Impl::ReconstructPrim<Material>(
|
||||
template <typename T>
|
||||
bool USDAReader::Impl::ReconstructPrim(
|
||||
const prim::PropertyMap &properties,
|
||||
const ReferenceList &references,
|
||||
const prim::ReferenceList &references,
|
||||
T *prim) {
|
||||
|
||||
std::string err;
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace tinyusdz {
|
||||
// in prim-types.hh
|
||||
class Path;
|
||||
struct StringData;
|
||||
struct Reference;
|
||||
struct Payload;
|
||||
|
||||
} // namespace tinyusdz
|
||||
|
||||
@@ -85,6 +87,9 @@ std::ostream &operator<<(std::ostream &os, const tinyusdz::value::AssetPath &v);
|
||||
std::ostream &operator<<(std::ostream &os, const tinyusdz::Path &v);
|
||||
std::ostream &operator<<(std::ostream &os, const tinyusdz::StringData &v);
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const tinyusdz::Reference &v);
|
||||
std::ostream &operator<<(std::ostream &os, const tinyusdz::Payload &v);
|
||||
|
||||
// 1D array
|
||||
template <typename T>
|
||||
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
|
||||
|
||||
16
tests/usda/fail-case/variantSet-in-prim-meta-000.usda
Normal file
16
tests/usda/fail-case/variantSet-in-prim-meta-000.usda
Normal file
@@ -0,0 +1,16 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "hello"
|
||||
)
|
||||
|
||||
def Xform "hello" (
|
||||
variants = {
|
||||
string shadingVariant = "green"
|
||||
string bora = "red"
|
||||
}
|
||||
prepend variantSets = "shadingVariant"
|
||||
variantSet = { "bora" { active = true } }
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/payload-000.usda
Normal file
8
tests/usda/payload-000.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
payload = @sphere.usda@
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/payload-001.usda
Normal file
8
tests/usda/payload-001.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
payload = [@sphere.usda@, @suzanne.usda@]
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/payload-005.usda
Normal file
8
tests/usda/payload-005.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
payload = None
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/references-002.usda
Normal file
8
tests/usda/references-002.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
references = @sphere.usda@</sphere>
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/references-003.usda
Normal file
8
tests/usda/references-003.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
references = [@sphere.usda@</sphere>, @suzanne.usda@</Suzanne>]
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/references-004.usda
Normal file
8
tests/usda/references-004.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
references = []
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
8
tests/usda/references-005.usda
Normal file
8
tests/usda/references-005.usda
Normal file
@@ -0,0 +1,8 @@
|
||||
#usda 1.0
|
||||
|
||||
def "sphere1" (
|
||||
references = None
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
36
tests/usda/variantSet-002.usda
Normal file
36
tests/usda/variantSet-002.usda
Normal file
@@ -0,0 +1,36 @@
|
||||
#usda 1.0
|
||||
|
||||
def Xform "Implicits" (
|
||||
append variantSets = "shapeVariant"
|
||||
)
|
||||
{
|
||||
# Prim meta in variant Stmt.
|
||||
variantSet "shapeVariant" = {
|
||||
|
||||
"Capsule" ( active = true ) {
|
||||
def Capsule "Pill"
|
||||
{
|
||||
}
|
||||
}
|
||||
"Cone" {
|
||||
def Cone "PartyHat"
|
||||
{
|
||||
}
|
||||
}
|
||||
"Cube" {
|
||||
def Cube "Box"
|
||||
{
|
||||
}
|
||||
}
|
||||
"Cylinder" {
|
||||
def Cylinder "Tube"
|
||||
{
|
||||
}
|
||||
}
|
||||
"Sphere" {
|
||||
def Sphere "Ball"
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user