diff --git a/src/ascii-parser.cc b/src/ascii-parser.cc index 448fec997..20b21833d 100644 --- a/src/ascii-parser.cc +++ b/src/ascii-parser.cc @@ -284,6 +284,9 @@ static void RegisterPrimMetas( // NOTE: items are expected to be all string type. metas["sdrMetadata"] = AsciiParser::VariableDef(value::kDictionary, "sdrMetadata"); + metas["clips"] = + AsciiParser::VariableDef(value::kDictionary, "clips"); + // USDZ extension metas["sceneName"] = AsciiParser::VariableDef(value::kString, "sceneName"); @@ -2489,6 +2492,8 @@ bool AsciiParser::ParseMetaValue(const VariableDef &def, MetaVariable *outvar) { bool array_qual{false}; + DCOUT("parseMeta: vartype " << vartype); + if (endsWith(vartype, "[]")) { vartype = removeSuffix(vartype, "[]"); array_qual = true; diff --git a/src/pprinter.cc b/src/pprinter.cc index 889ac8ed3..87141fb4a 100644 --- a/src/pprinter.cc +++ b/src/pprinter.cc @@ -466,6 +466,10 @@ std::string print_prim_metas(const PrimMeta &meta, const uint32_t indent) { ss << pprint::Indent(indent) << "active = " << to_string(meta.active.value()) << "\n"; } + if (meta.clips) { + ss << print_customData(meta.clips.value(), "clips", indent); + } + if (meta.instanceable) { ss << pprint::Indent(indent) << "instanceable = " << to_string(meta.instanceable.value()) << "\n"; } diff --git a/src/prim-types.cc b/src/prim-types.cc index 39693e70c..f28b751cf 100644 --- a/src/prim-types.cc +++ b/src/prim-types.cc @@ -1791,6 +1791,14 @@ void PrimMetas::update_from(const PrimMetas &rhs, const bool override_authored) } } + if (rhs.clips) { + if (clips) { + OverrideDictionary(clips.value(), rhs.clips.value(), override_authored); + } else if (override_authored) { + clips = rhs.clips; + } + } + if (rhs.customData) { if (customData) { OverrideDictionary(customData.value(), rhs.customData.value(), override_authored); diff --git a/src/prim-types.hh b/src/prim-types.hh index acf53b7aa..727c903f3 100644 --- a/src/prim-types.hh +++ b/src/prim-types.hh @@ -807,6 +807,7 @@ struct PrimMetas { sdrMetadata; // 'sdrMetadata' (usdShade Prim only?) nonstd::optional instanceable; // 'instanceable' + nonstd::optional clips; // 'clips' // String representation of Kind. // For user-defined Kind, it returns `_kind_str` @@ -868,7 +869,7 @@ struct PrimMetas { return (active || hidden || kind || customData || references || payload || inherits || variants || variantSets || specializes || displayName || sceneName || doc || comment || unregisteredMetas.size() || meta.size() || apiSchemas || - sdrMetadata || assetInfo || instanceable); + sdrMetadata || assetInfo || instanceable || clips); } // diff --git a/src/usda-reader.cc b/src/usda-reader.cc index 1e103f79f..74c44d86e 100644 --- a/src/usda-reader.cc +++ b/src/usda-reader.cc @@ -897,6 +897,24 @@ class USDAReader::Impl { "`dictionary`. got type `" << var.type_name() << "`"); } + } else if (meta.first == "clips") { + DCOUT("clips. type = " << var.type_name()); + if (var.type_id() == value::TypeTraits::type_id()) { + if (auto pv = var.get_value()) { + out->clips = pv.value(); + } else { + PUSH_ERROR_AND_RETURN_TAG(kTag, + "(Internal error?) `clips` metadataum is not type " + "`dictionary`. got type `" + << var.type_name() << "`"); + } + + } else { + PUSH_ERROR_AND_RETURN( + "(Internal error?) `clips` metadataum is not type " + "`dictionary`. got type `" + << var.type_name() << "`"); + } } else if (meta.first == "assetInfo") { DCOUT("assetInfo. type = " << var.type_name()); if (auto pv = var.get_value()) { diff --git a/src/usdc-reader.cc b/src/usdc-reader.cc index 2b0c22731..d54bffbb1 100644 --- a/src/usdc-reader.cc +++ b/src/usdc-reader.cc @@ -1829,6 +1829,15 @@ bool USDCReader::Impl::ParsePrimSpec(const crate::FieldValuePairVector &fvs, kTag, "`assetInfo` must be type `dictionary`, but got type `" << fv.second.type_name() << "`"); } + } else if (fv.first == "clips") { + // CustomData(dict) + if (auto pv = fv.second.as()) { + primMeta.clips = (*pv); + } else { + PUSH_ERROR_AND_RETURN_TAG( + kTag, "`clips` must be type `dictionary`, but got type `" + << fv.second.type_name() << "`"); + } } else if (fv.first == "kind") { if (auto pv = fv.second.as()) { diff --git a/tests/usda/clips-primmeta-001.usda b/tests/usda/clips-primmeta-001.usda new file mode 100644 index 000000000..213fb83cd --- /dev/null +++ b/tests/usda/clips-primmeta-001.usda @@ -0,0 +1,14 @@ +#usda 1.0 + over "GEO" ( + clips = { + dictionary geo = { + double2[] active = [(1004, 0)] + asset[] assetPaths = [@payload/animated_data.1004.usdc@] + asset manifestAssetPath = @./clip.manifest.usda@ + string primPath = "/root/remi/body_M_hrc/GEO" + double2[] times = [] + } + } + ) +{ } + diff --git a/tests/usdc/clips-primmeta-001.usdc b/tests/usdc/clips-primmeta-001.usdc new file mode 100644 index 000000000..ca7f597c3 Binary files /dev/null and b/tests/usdc/clips-primmeta-001.usdc differ