From 45d72234c6339ec6adecbd6f308f292ab7c25fb5 Mon Sep 17 00:00:00 2001 From: Syoyo Fujita Date: Mon, 7 Aug 2023 22:38:02 +0900 Subject: [PATCH] [USDC parser] Support parsing variantSet statement --- src/prim-types.cc | 1 + src/prim-types.hh | 2 + src/usdc-reader.cc | 538 ++++++++++++++++------------ tests/usda/variantSet-meta-001.usda | 29 ++ tests/usda/variantSet-meta-002.usda | 17 + tests/usda/variantSet-prim-001.usda | 23 ++ tests/usdc/variantSet-meta-001.usdc | Bin 0 -> 1037 bytes tests/usdc/variantSet-meta-002.usdc | Bin 0 -> 777 bytes tests/usdc/variantSet-prim-001.usdc | Bin 0 -> 949 bytes 9 files changed, 382 insertions(+), 228 deletions(-) create mode 100644 tests/usda/variantSet-meta-001.usda create mode 100644 tests/usda/variantSet-meta-002.usda create mode 100644 tests/usda/variantSet-prim-001.usda create mode 100644 tests/usdc/variantSet-meta-001.usdc create mode 100644 tests/usdc/variantSet-meta-002.usdc create mode 100644 tests/usdc/variantSet-prim-001.usdc diff --git a/src/prim-types.cc b/src/prim-types.cc index 17b11299c..670605a99 100644 --- a/src/prim-types.cc +++ b/src/prim-types.cc @@ -497,6 +497,7 @@ Path Path::append_element(const std::string &elem) { return p; } + // {variant=value} if (is_variantElementName(elem)) { std::array variant; if (tokenize_variantElement(elem, &variant)) { diff --git a/src/prim-types.hh b/src/prim-types.hh index 1d6d9b2b4..1f8e16b6a 100644 --- a/src/prim-types.hh +++ b/src/prim-types.hh @@ -467,6 +467,7 @@ class Path { return true; // prop part only } +#if 0 // TODO: rmove bool is_variant_selection_path() const { if (!is_valid()) { return false; @@ -478,6 +479,7 @@ class Path { return false; } +#endif // Strip '/' Path &make_relative() { diff --git a/src/usdc-reader.cc b/src/usdc-reader.cc index 362127130..fc0c8e2ae 100644 --- a/src/usdc-reader.cc +++ b/src/usdc-reader.cc @@ -8,6 +8,7 @@ // - [ ] Validate the existence of connection Paths(Connection) and target // Paths(Relation) // - [ ] GeomSubset +// - [ ] Refactor Variant related code. // #ifdef _MSC_VER @@ -105,46 +106,6 @@ namespace usdc { constexpr auto kTag = "[USDC]"; -#if 0 -struct PrimNode { - value::Value - prim; // Usually stores reconstructed(composed) concrete Prim(e.g. Xform) - - int64_t parent{-1}; // -1 = root node - std::vector children; // index to USDCReader::Impl::._prim_nodes[] - - // - // - // - std::vector primChildren; - -#if 0 - // - // For Variants - /// - // SpecType::VariantSet - std::vector variantChildren; - - // TODO: Variants - std::map variants; -#else - -#endif -}; - -struct VariantPrimNode { - int64_t parent{-1}; // -1 = root node - - // - // For Variants - /// - // SpecType::VariantSet - std::vector variantChildren; - - value::Value prim; // Usually stores reconstructed Prim(e.g. Xform) -}; -#endif - // TODO: Unify with ascii-parser.cc static void RegisterPrimAttrTypes(std::set &d) { d.clear(); @@ -295,23 +256,6 @@ class USDCReader::Impl { bool ParseProperty(const SpecType specType, const crate::FieldValuePairVector &fvs, Property *prop); -#if 0 // TODO: Remove - // For simple, non animatable and non `.connect` types. e.g. "token[]" - template - bool ReconstructSimpleAttribute(int parent, - const crate::FieldValuePairVector &fvs, - T *attr, bool *custom_out = nullptr, - Variability *variability_out = nullptr); -#endif - -#if 0 - // For attribute which maybe a value, connection or TimeSamples. - template - bool ReconstructTypedProperty(int parent, - const crate::FieldValuePairVector &fvs, - TypedProperty *attr); -#endif - /// /// Parse Prim spec from FieldValuePairs /// @@ -379,7 +323,7 @@ class USDCReader::Impl { /// /// For Layer /// - + bool ReconstructPrimSpecRecursively(int parent_id, int current_id, PrimSpec *rootPrim, int level, const PathIndexToSpecIndexMap &psmap, @@ -489,8 +433,10 @@ class USDCReader::Impl { // For Prim/Props defined as Variant(SpecType::VariantSet) // key = path index. - std::map _variantPrims; - std::map _variantProps; + std::map _variantPrims; // For Stage + std::map _variantPrimSpecs; // For Layer + std::map> _variantProps; + std::map _variants; // key = parent path index, values = key to `_variantPrims`, `_variantProps` std::map> _variantPrimChildren; @@ -1387,134 +1333,6 @@ bool USDCReader::Impl::ParseProperty(const SpecType spec_type, return true; } -#if 0 // TODO: Remove -template -bool USDCReader::Impl::ReconstructSimpleAttribute( - int parent, const crate::FieldValuePairVector &fvs, T *attr, - bool *custom_out, Variability *variability_out) { - (void)attr; - - if (fvs.size() > _config.kMaxFieldValuePairs) { - PUSH_ERROR_AND_RETURN_TAG(kTag, "Too much FieldValue pairs."); - } - - bool valid{false}; - - for (auto &fv : fvs) { - // Some predefined fields - if (fv.first == "custom") { - if (auto pv = fv.second.get_value()) { - if (custom_out) { - (*custom_out) = pv.value(); - } - } else { - PUSH_ERROR_AND_RETURN_TAG(kTag, "`custom` field is not `bool` type."); - } - } else if (fv.first == "variability") { - if (auto pv = fv.second.get_value()) { - if (variability_out) { - (*variability_out) = pv.value(); - } - } else { - PUSH_ERROR_AND_RETURN_TAG( - kTag, "`variability` field is not `varibility` type."); - } - } else if (fv.first == "typeName") { - if (auto pv = fv.second.get_value()) { - DCOUT("typeName = " << pv.value().str()); - if (value::TypeTraits::type_name() != pv.value().str()) { - PUSH_ERROR_AND_RETURN_TAG( - kTag, "Property type mismatch. `" - << value::TypeTraits::type_name() - << "` expected but got `" << pv.value().str() << "`."); - } - } else { - PUSH_ERROR_AND_RETURN_TAG(kTag, - "`typeName` field is not `token` type."); - } - } else if (fv.first == "default") { - if (fv.second.type_id() != value::TypeTraits::type_id()) { - PUSH_ERROR_AND_RETURN_TAG(kTag, "Property type mismatch. `" - << value::TypeTraits::type_name() - << "` expected but got `" - << fv.second.type_name() << "`."); - } - - if (auto pv = fv.second.get_value()) { - (*attr) = pv.value(); - } else { - PUSH_ERROR_AND_RETURN_TAG(kTag, "Type mismatch. Internal error."); - } - valid = true; - } - - DCOUT("parent[" << parent << "] fv name " << fv.first - << "(type = " << fv.second.type_name() << ")"); - } - - if (!valid) { - PUSH_ERROR_AND_RETURN_TAG(kTag, "`default` field not found."); - } - - return true; -} -#endif - -#if 0 -template -bool USDCReader::Impl::ReconstructTypedProperty( - int parent, const crate::FieldValuePairVector &fvs, - TypedProperty *attr) { - (void)attr; - - if (fvs.size() > _config.kMaxFieldValuePairs) { - PUSH_ERROR_AND_RETURN_TAG(kTag, "Too much FieldValue pairs."); - } - - for (auto &fv : fvs) { - // Some predefined fields - if (fv.first == "custom") { - if (auto pv = fv.second.get_value()) { - attr->custom = pv.value(); - } else { - PUSH_ERROR_AND_RETURN_TAG(kTag, "`custom` field is not `bool` type."); - } - } else if (fv.first == "typeName") { - if (auto pv = fv.second.get_value()) { - DCOUT("typeName = " << pv.value().str()); - if (value::TypeTraits::type_name() != pv.value().str()) { - PUSH_ERROR_AND_RETURN_TAG( - kTag, "Property type mismatch. `" - << value::TypeTraits::type_name() - << "` expected but got `" << pv.value().str() << "`."); - } - } else { - PUSH_ERROR_AND_RETURN_TAG(kTag, - "`typeName` field is not `token` type."); - } - } else if (fv.first == "default") { - if (fv.second.type_id() != value::TypeTraits::type_id()) { - PUSH_ERROR_AND_RETURN_TAG(kTag, "Property type mismatch. `" - << value::TypeTraits::type_name() - << "` expected but got `" - << fv.second.type_name() << "`."); - } - - if (auto pv = fv.second.get_value()) { - Animatable anim; - anim.value = pv.value(); - attr->value = anim; - } - } - - DCOUT("parent[" << parent << "] fv name " << fv.first - << "(type = " << fv.second.type_name() << ")"); - } - - return true; -} -#endif - template bool USDCReader::Impl::ReconstructPrim(const crate::CrateReader::Node &node, const PathIndexToSpecIndexMap &psmap, @@ -2639,11 +2457,12 @@ bool USDCReader::Impl::ReconstructPrimNode(int parent, int current, int level, variantPrim.value().specifier() = specifier.value(); // Store variantPrim to temporary buffer. - DCOUT("add prim idx as variant: " << current); + DCOUT(fmt::format("parent {} add prim idx {} as variant: ", parent, current)); if (_variantPrims.count(current)) { DCOUT("??? prim idx already set " << current); } else { _variantPrims.emplace(current, variantPrim.value()); + _variantPrimChildren[parent].push_back(current); } } else { if (_config.allow_unknown_prims && is_unsupported_prim) { @@ -2661,11 +2480,12 @@ bool USDCReader::Impl::ReconstructPrimNode(int parent, int current, int level, variantPrim.value().specifier() = specifier.value(); // Store variantPrim to temporary buffer. - DCOUT("add prim idx as variant: " << current); + DCOUT(fmt::format("parent {} add prim idx {} as variant: ", parent, current)); if (_variantPrims.count(current)) { DCOUT("??? prim idx already set " << current); } else { _variantPrims.emplace(current, variantPrim.value()); + _variantPrimChildren[parent].push_back(current); } } else { return false; @@ -2695,11 +2515,12 @@ bool USDCReader::Impl::ReconstructPrimNode(int parent, int current, int level, // Parent Prim is not yet reconstructed, so store info to temporary // buffer _variantAttributeNodes. - _variantProps.emplace(current, prop); + _variantProps[current] = {path.value(), prop}; + _variantPropChildren[parent].push_back(current); DCOUT( - fmt::format("[{}] Parsed Attribute {} under Variant. PathIndex {}", - current, path.value().prop_part(), spec.path_index)); + fmt::format("parent {} current [{}] Parsed Attribute {} under Variant. PathIndex {}", + parent, current, path.value().prop_part(), spec.path_index)); } else { // Maybe parent is Class/Over, or inherited @@ -3066,7 +2887,6 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve pTyName = typeName.value(); } - nonstd::optional variantPrim; { std::string prim_name = elemPath.prim_part(); DCOUT("elemPath = " << dump_path(elemPath)); @@ -3091,6 +2911,8 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve variantPrimName)); } +#if 0 + nonstd::optional variantPrimSpec; bool is_unsupported_prim{false}; variantPrim = ReconstructPrimFromTypeName( pTyName, primTypeName, variantPrimName, node, specifier.value(), primChildren, properties, @@ -3105,7 +2927,7 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve variantPrim.value().specifier() = specifier.value(); // Store variantPrim to temporary buffer. - DCOUT("add prim idx as variant: " << current); + DCOUT(fmt::format("parent {} add prim idx {} as variant: ", parent, current)); if (_variantPrims.count(current)) { DCOUT("??? prim idx already set " << current); } else { @@ -3128,7 +2950,7 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve variantPrim.value().specifier() = specifier.value(); // Store variantPrim to temporary buffer. - DCOUT("add prim idx as variant: " << current); + DCOUT(fmt::format("parent {} add prim idx {} as variant: ", parent, current)); if (_variantPrims.count(current)) { DCOUT("??? prim idx already set " << current); } else { @@ -3142,6 +2964,28 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve return false; } } +#else + PrimSpec variantPrimSpec; + variantPrimSpec.typeName() = primTypeName; + variantPrimSpec.name() = prim_name; + + prim::PropertyMap props; + if (!BuildPropertyMap(node.GetChildren(), psmap, &props)) { + PUSH_ERROR_AND_RETURN_TAG(kTag, "Failed to build PropertyMap."); + } + variantPrimSpec.props() = props; + variantPrimSpec.metas() = primMeta; + + // Store variantPrimSpec to temporary buffer. + DCOUT(fmt::format("parent {} add primspec idx {} as variant: ", parent, current)); + if (_variantPrimSpecs.count(current)) { + DCOUT("??? prim idx already set " << current); + } else { + _variantPrimSpecs.emplace(current, variantPrimSpec); + _variantPrimChildren[parent].push_back(current); + } + +#endif } break; @@ -3163,12 +3007,12 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve // Parent Prim is not yet reconstructed, so store info to temporary // buffer _variantAttributeNodes. - _variantProps.emplace(current, prop); + _variantProps[current] = {path.value(), prop}; _variantPropChildren[parent].push_back(current); DCOUT( - fmt::format("[{}] Parsed Attribute {} under Variant. PathIndex {}", - current, path.value().prop_part(), spec.path_index)); + fmt::format("parent {} current [{}] Parsed Attribute {} under Variant. PathIndex {}", + parent, current, path.value().prop_part(), spec.path_index)); } else { // Maybe parent is Class/Over, or inherited @@ -3203,8 +3047,11 @@ bool USDCReader::Impl::ReconstructPrimSpecNode(int parent, int current, int leve return true; } +// +// TODO: rewrite code in bottom-up manner +// bool USDCReader::Impl::ReconstructPrimRecursively( - int parent, int current, Prim *rootPrim, int level, + int parent, int current, Prim *parentPrim, int level, const PathIndexToSpecIndexMap &psmap, Stage *stage) { if (level > int32_t(_config.kMaxPrimNestLevel)) { PUSH_ERROR_AND_RETURN_TAG(kTag, "Prim hierarchy is too deep."); @@ -3220,33 +3067,15 @@ bool USDCReader::Impl::ReconstructPrimRecursively( return false; } -#if 0 // not used - crate::Spec spec; - { - if (!psmap.count(uint32_t(current))) { - PUSH_ERROR_AND_RETURN_TAG(kTag, fmt::format("Spec index {} not found in parent Prim index {}", current, parent)); - } - - uint32_t spec_index = psmap.at(uint32_t(current)); - - if (spec_index >= _specs.size()) { - PUSH_ERROR("Invalid specifier id: " + std::to_string(spec_index) + - ". Must be in range [0, " + std::to_string(_specs.size()) + ")"); - return false; - } - - spec = _specs[spec_index]; - } -#endif - - // TODO: Refactor + // + // TODO: Use bottom-up reconstruction(traverse child first) + // // null : parent node is Property or other Spec type. // non-null : parent node is Prim Prim *currPrimPtr = nullptr; nonstd::optional prim; - // Assume parent node is already processed. bool is_parent_variant = _variantPrims.count(parent); if (!ReconstructPrimNode(parent, current, level, is_parent_variant, psmap, @@ -3258,6 +3087,7 @@ bool USDCReader::Impl::ReconstructPrimRecursively( currPrimPtr = &(prim.value()); } + // Traverse children { const crate::CrateReader::Node &node = _nodes[size_t(current)]; DCOUT("node.Children.size = " << node.GetChildren().size()); @@ -3273,14 +3103,140 @@ bool USDCReader::Impl::ReconstructPrimRecursively( } } + // + // Reonstruct variant + // + DCOUT(fmt::format("parent {}, current {}", parent, current)); + + DCOUT(fmt::format(" has variant properties {}, has variant children {}", + _variantPropChildren.count(current), + _variantPrimChildren.count(current))); + + if (_variantPropChildren.count(current)) { + + // - parentPrim + // - variantPrim(SpecTypeVariant) <- current + // - variant property(SpecTypeAttribute) + + // + // `current` must be VariantPrim and `parentPrim` should exist + // + if (!_variantPrims.count(current)) { + PUSH_ERROR_AND_RETURN("Internal error: variant attribute is not a child of VariantPrim."); + } + + if (!parentPrim) { + PUSH_ERROR_AND_RETURN("Internal error: parentPrim should exist."); + } + + const Prim &variantPrim = _variantPrims.at(current); + + DCOUT("variant prim name: " << variantPrim.element_name()); + + + // element_name must be variant: "{variant=value}" + if (!is_variantElementName(variantPrim.element_name())) { + PUSH_ERROR_AND_RETURN("Corrupted Crate. VariantAttribute is not the child of VariantPrim."); + } + + std::array toks; + if (!tokenize_variantElement(variantPrim.element_name(), &toks)) { + PUSH_ERROR_AND_RETURN("Invalid variant element_name."); + } + + std::string variantSetName = toks[0]; + std::string variantName = toks[1]; + + Variant variant; + + for (const auto &item : _variantPropChildren.at(current)) { + // item should exist in _variantProps. + if (!_variantProps.count(item)) { + PUSH_ERROR_AND_RETURN("Internal error: variant Property not found."); + } + const std::pair &pp = _variantProps.at(item); + + std::string prop_name = std::get<0>(pp).prop_part(); + DCOUT(fmt::format(" node_index = {}, prop name {}", item, prop_name)); + + variant.properties()[prop_name] = std::get<1>(pp); + } + + VariantSet &vs = parentPrim->variantSets()[variantSetName]; + + if (vs.name.empty()) { + vs.name = variantSetName; + } + vs.variantSet[variantName] = variant; + + } + + if (_variantPrimChildren.count(current)) { + + // - currentPrim <- current + // - variant Prim children + + if (!prim) { + PUSH_ERROR_AND_RETURN("Internal error: must be Prim."); + } + + DCOUT(fmt::format("{} has variant Prim ", prim->element_name())); + + + for (const auto &item : _variantPrimChildren.at(current)) { + + if (!_variantPrims.count(item)) { + PUSH_ERROR_AND_RETURN("Internal error: variant Prim children not found."); + } + + const Prim &vp = _variantPrims.at(item); + + DCOUT(fmt::format(" variantPrim name {}", vp.element_name())); + + // element_name must be variant: "{variant=value}" + if (!is_variantElementName(vp.element_name())) { + PUSH_ERROR_AND_RETURN("Corrupted Crate. Variant Prim has invalid element_name."); + } + + std::array toks; + if (!tokenize_variantElement(vp.element_name(), &toks)) { + PUSH_ERROR_AND_RETURN("Invalid variant element_name."); + } + + std::string variantSetName = toks[0]; + std::string variantName = toks[1]; + + VariantSet &vs = prim->variantSets()[variantSetName]; + + if (vs.name.empty()) { + vs.name = variantSetName; + } + vs.variantSet[variantName].metas() = vp.metas(); + DCOUT("# of primChildren = " << vp.children().size()); + vs.variantSet[variantName].primChildren() = std::move(vp.children()); + + } + } + if (parent == 0) { // root prim if (prim) { stage->root_prims().emplace_back(std::move(prim.value())); } } else { - // Add to root prim. - if (prim && rootPrim) { - rootPrim->children().emplace_back(std::move(prim.value())); + if (_variantPrims.count(parent)) { + // Add to variantPrim + DCOUT("parent is variantPrim: " << parent); + if (!prim) { + // FIXME: Validate current should be Prim. + PUSH_WARN("parent is variantPrim, but current is not Prim."); + } else { + DCOUT("Adding prim to child..."); + Prim &vp = _variantPrims.at(parent); + vp.children().emplace_back(std::move(prim.value())); + } + } else if (prim && parentPrim) { + // Add to parent prim. + parentPrim->children().emplace_back(std::move(prim.value())); } } @@ -3344,7 +3300,7 @@ bool USDCReader::Impl::ReconstructStage(Stage *stage) { } bool USDCReader::Impl::ReconstructPrimSpecRecursively( - int parent, int current, PrimSpec *rootPrimSpec, int level, + int parent, int current, PrimSpec *parentPrimSpec, int level, const PathIndexToSpecIndexMap &psmap, Layer *layer) { if (level > int32_t(_config.kMaxPrimNestLevel)) { PUSH_ERROR_AND_RETURN_TAG(kTag, "PrimSpec hierarchy is too deep."); @@ -3394,14 +3350,140 @@ bool USDCReader::Impl::ReconstructPrimSpecRecursively( } } + // + // Reonstruct variant + // + DCOUT(fmt::format("parent {}, current {}", parent, current)); + + DCOUT(fmt::format(" has variant properties {}, has variant children {}", + _variantPropChildren.count(current), + _variantPrimChildren.count(current))); + + if (_variantPropChildren.count(current)) { + + // - parentPrim + // - variantPrim(SpecTypeVariant) <- current + // - variant property(SpecTypeAttribute) + + // + // `current` must be VariantPrim and `parentPrim` should exist + // + if (!_variantPrims.count(current)) { + PUSH_ERROR_AND_RETURN("Internal error: variant attribute is not a child of VariantPrim."); + } + + if (!parentPrimSpec) { + PUSH_ERROR_AND_RETURN("Internal error: parentPrimSpec should exist."); + } + + const Prim &variantPrim = _variantPrims.at(current); + + DCOUT("variant prim name: " << variantPrim.element_name()); + + + // element_name must be variant: "{variant=value}" + if (!is_variantElementName(variantPrim.element_name())) { + PUSH_ERROR_AND_RETURN("Corrupted Crate. VariantAttribute is not the child of VariantPrim."); + } + + std::array toks; + if (!tokenize_variantElement(variantPrim.element_name(), &toks)) { + PUSH_ERROR_AND_RETURN("Invalid variant element_name."); + } + + std::string variantSetName = toks[0]; + std::string variantName = toks[1]; + + PrimSpec variant; + + for (const auto &item : _variantPropChildren.at(current)) { + // item should exist in _variantProps. + if (!_variantProps.count(item)) { + PUSH_ERROR_AND_RETURN("Internal error: variant Property not found."); + } + const std::pair &pp = _variantProps.at(item); + + std::string prop_name = std::get<0>(pp).prop_part(); + DCOUT(fmt::format(" node_index = {}, prop name {}", item, prop_name)); + + variant.props()[prop_name] = std::get<1>(pp); + } + + VariantSetSpec &vs = parentPrimSpec->variantSets()[variantSetName]; + + if (vs.name.empty()) { + vs.name = variantSetName; + } + vs.variantSet[variantName] = variant; + + } + + if (_variantPrimChildren.count(current)) { + + // - currentPrim <- current + // - variant Prim children + + if (!primspec) { + PUSH_ERROR_AND_RETURN("Internal error: must be Prim."); + } + + DCOUT(fmt::format("{} has variant PrimSpec ", primspec->name())); + + + for (const auto &item : _variantPrimChildren.at(current)) { + + if (!_variantPrimSpecs.count(item)) { + PUSH_ERROR_AND_RETURN("Internal error: variant Prim children not found."); + } + + const PrimSpec &vp = _variantPrimSpecs.at(item); + + DCOUT(fmt::format(" variantPrim name {}", vp.name())); + + // element_name must be variant: "{variant=value}" + if (!is_variantElementName(vp.name())) { + PUSH_ERROR_AND_RETURN("Corrupted Crate. Variant Prim has invalid element_name."); + } + + std::array toks; + if (!tokenize_variantElement(vp.name(), &toks)) { + PUSH_ERROR_AND_RETURN("Invalid variant element_name."); + } + + std::string variantSetName = toks[0]; + std::string variantName = toks[1]; + + VariantSetSpec &vs = primspec->variantSets()[variantSetName]; + + if (vs.name.empty()) { + vs.name = variantSetName; + } + vs.variantSet[variantName].metas() = vp.metas(); + DCOUT("# of primChildren = " << vp.children().size()); + vs.variantSet[variantName].children() = std::move(vp.children()); + + } + } + if (parent == 0) { // root prim if (primspec) { layer->primspecs().emplace(primspec.value().name(), std::move(primspec.value())); } } else { - // Add to root prim. - if (primspec && rootPrimSpec) { - rootPrimSpec->children().emplace_back(std::move(primspec.value())); + if (_variantPrimSpecs.count(parent)) { + // Add to variantPrim + DCOUT("parent is variantPrim: " << parent); + if (!primspec) { + // FIXME: Validate current should be Prim. + PUSH_WARN("parent is variantPrim, but current is not Prim."); + } else { + DCOUT("Adding prim to child..."); + PrimSpec &vps = _variantPrimSpecs.at(parent); + vps.children().emplace_back(std::move(primspec.value())); + } + } else if (primspec && parentPrimSpec) { + // Add to parent prim. + parentPrimSpec->children().emplace_back(std::move(primspec.value())); } } diff --git a/tests/usda/variantSet-meta-001.usda b/tests/usda/variantSet-meta-001.usda new file mode 100644 index 000000000..c0a17d9e5 --- /dev/null +++ b/tests/usda/variantSet-meta-001.usda @@ -0,0 +1,29 @@ +#usda 1.0 + +def "bora" ( + append variantSets = ["ashapeVariant2", "shapeVariant"] + variants = { + string ashapeVariant2 = "Capsule" + string shapeVariant = "Capsule" + } +) +{ + variantSet "ashapeVariant2" = { + "Capsule" ( hidden = 1 ) { + float mycapsule = 0.4 + } + "Cone" ( hidden = 1 ) { + float mycone = 0.2 + } + } + + variantSet "shapeVariant" = { + "Capsule" ( hidden = 0 ) { + float mycapsule = 1.3 + } + "Cone" ( hidden = 0 ) { + float mycone = 2.3 + } + } + +} diff --git a/tests/usda/variantSet-meta-002.usda b/tests/usda/variantSet-meta-002.usda new file mode 100644 index 000000000..ccfa93486 --- /dev/null +++ b/tests/usda/variantSet-meta-002.usda @@ -0,0 +1,17 @@ +#usda 1.0 + +def "bora" ( + append variantSets = ["shapeVariant"] + variants = { + string shapeVariant = "Capsule" + } +) +{ + variantSet "shapeVariant" = { + "Capsule" ( hidden = 0 ) { + } + "Cone" ( hidden = 1 ) { + } + } + +} diff --git a/tests/usda/variantSet-prim-001.usda b/tests/usda/variantSet-prim-001.usda new file mode 100644 index 000000000..3a8d7036b --- /dev/null +++ b/tests/usda/variantSet-prim-001.usda @@ -0,0 +1,23 @@ +#usda 1.0 + +def "bora" ( + append variantSets = ["shapeVariant"] + variants = { + string shapeVariant = "Capsule" + } +) +{ + variantSet "shapeVariant" = { + "Capsule" ( hidden = 0 ) { + def "bora" { + float mycapsule = 1.3 + } + } + "Cone" ( hidden = 1 ) { + def "bora" { + float mycone = 2.3 + } + } + } + +} diff --git a/tests/usdc/variantSet-meta-001.usdc b/tests/usdc/variantSet-meta-001.usdc new file mode 100644 index 0000000000000000000000000000000000000000..c4fa72f9e27a1e55e14899c92ed5cb2f646c0168 GIT binary patch literal 1037 zcmbtTQESss6#j0~tXVrXb;}sChi#xzu>+kx$uy&jIvlgCiB1q9Yf~C%n~e~b#eU`m#Px>IJupb~;eX!G&X7{!?TYdIG?m6fCzMOOKxk+wqHDl%%vyjm< zUF`e+T?sG1ye14(W58g};s}dyiDE+oI<~hY*HMRa1MztpPco3&W8U>sKLrk_Z)MV0 zcYO<UyAA6C6=dG;gAcdS})9cM9vjdA=Yc{^CKs&*Y&%d0mk z_5?O6b|G-wS_*1Vz|E{%OG8p|VXKCZ^G%eUVv&}vZWf+m$Map!_5;VR&q90-r8x^c z!8Zh;^aj)wlm592~R(LGFr?c}ed@G~j4lCd8n{H4gVTkct__puPu zfYcc}61y?=gb^>%&{R#aI}$sX`9i*4{5*O>5;hQ3HA0Y1tkWT3R5=kzw%PXBGti3- zSvLs;K|GR0QHit%EHKANJd{Ebw%NDJ%y{@fU&;4lw(j!qJNJ2Gb!p|^so))JM{TU{ yaCb>xUOc6-%lVi8@VXI6p70-r-a^lE3&#D3W56rUulH%>b9#1=|HJuZ&L0C-=a@DC literal 0 HcmV?d00001 diff --git a/tests/usdc/variantSet-meta-002.usdc b/tests/usdc/variantSet-meta-002.usdc new file mode 100644 index 0000000000000000000000000000000000000000..a1126063d88734b5273e660709779066a5521947 GIT binary patch literal 777 zcmbtSO-lkn7=A`kw=d9xBy_Pu2Lq$1PEjc9mQt9wt9YwTM_lk@Tg{6I^#g(+=oa)7 zx_9ayMTh7Ew3*!*ji6I6%slV=KJPp8%txV8OqTSF3I(pEeIEXICSn1ODH-tGZ(qg% z#>u@y%%5c=%m%k-4=@mj*Z58{fwPWd!gj2d+OV26hqi&PO{-Sjq7J$Z)23z9vCMW4 zeFbksr@g${qFtz_-Mwhi82U|G?OC061ks*>ZMD-*AP_}taDw6P5DlwVTZF%krQsS* z8B2!~iCiw1DXz_x>#DnS50NI=l49c(cIa>-0Fz}_Q#Az}%Q$Cq5?2Z~6S!7DLU;rb z7e!JFqBknnc=7XliWW))W8YWsGxVXna|zre&UhhU^IA6MW#VCuc^dJLe1vf-j_vtmJs=N$^?0>jh2y$@|4;+Y|gZNB&X* literal 0 HcmV?d00001 diff --git a/tests/usdc/variantSet-prim-001.usdc b/tests/usdc/variantSet-prim-001.usdc new file mode 100644 index 0000000000000000000000000000000000000000..fc05fbffb5f77b0687a4714f420794920cb328e8 GIT binary patch literal 949 zcmbtS&ubGw6#izno81`H#3mT2QnA*NH z^Z$DjF2KAl9xV1R7H@@eqPI%%nT6c*3-|)Xd3u$tX$pksOVL(6xqeuzB{hootTb*pCws9Ihy?Am$kb?sK@4*D77LIc;U zgMJZ84*4gKF}^iM$8EPSLUzy`qc>{p;)CZ8JlhXlJE#H*|^M>XAX$SbTgG)j>x}dnGie@RAHNLG+k6+ z(a2T3tzmTqyYw#MnTB!^FEtPq6%hSR601cJ$`Sp&hC~6GY#J*mT}8BnYr5mSyA5c1 zxxB11f0_5VB6>wxw(nfSG)*O&MJ$~pj@9E>N*pDRVo5tp9i*h6NuDkISyBCw6%#5U zpGs*F{1L@*Y-Wgjnv#AM_QmA*PQ$UWNeko&fzV=qVroyPS`?n+0eqDyGU+ZPMN;PS zOeSLzRhcYJPLSZ)#)EscdQ+4FpE&%+ebd<5sNbC@JZJ5w3Eevzwfk#x8m~D2VwQ#( jUo%9?CH}E*aK2G7)&<8xo18Z|-)z*Xi~L*8uXFwnLR5!* literal 0 HcmV?d00001