// Helper function to make reading from dictionaries easier static bool _GetKey(const JsObject &dict, const std::string &key, JsObject *value) { JsObject::const_iterator i = dict.find(key); if (i != dict.end() && i->second.IsObject()) { *value = i->second.GetObject(); return true; } return false; }
static std::string _GetExportAttributeMetadata( const JsObject& attrMetadata, const TfToken& keyToken) { std::string value; JsObject::const_iterator attrMetadataIter = attrMetadata.find(keyToken); if (attrMetadataIter != attrMetadata.end()) { value = attrMetadataIter->second.GetString(); } return value; }
static bool _GetExportAttributeMetadata( const JsObject& attrMetadata, const TfToken& keyToken, const bool defaultValue) { bool value = defaultValue; JsObject::const_iterator attrMetadataIter = attrMetadata.find(keyToken); if (attrMetadataIter != attrMetadata.end()) { value = attrMetadataIter->second.GetBool(); } return value; }
void KindRegistry::_RegisterDefaults() { // Initialize builtin kind hierarchy. _Register(KindTokens->subcomponent); _Register(KindTokens->model); _Register(KindTokens->component, KindTokens->model); _Register(KindTokens->group, KindTokens->model); _Register(KindTokens->assembly, KindTokens->group); // Check plugInfo for extensions to the kind hierarchy. // // XXX We only do this once, and do not re-build the kind hierarchy // if someone manages to add more plugins while the app is running. // This allows the KindRegistry to be threadsafe without locking. const PlugPluginPtrVector& plugins = PlugRegistry::GetInstance().GetAllPlugins(); TF_FOR_ALL(plug, plugins){ JsObject kinds; const JsObject &metadata = (*plug)->GetMetadata(); if (!_GetKey(metadata, _tokens->PluginKindsKey, &kinds)) continue; TF_FOR_ALL(kindEntry, kinds){ // Each entry is a map from kind -> metadata dict. TfToken kind(kindEntry->first); JsObject kindDict; if (!_GetKey(kinds, kind, &kindDict)){ TF_RUNTIME_ERROR("Expected dict for kind '%s'", kind.GetText()); continue; } // Check for baseKind. TfToken baseKind; JsObject::const_iterator i = kindDict.find("baseKind"); if (i != kindDict.end()) { if (i->second.IsString()) { baseKind = TfToken(i->second.GetString()); } else { TF_RUNTIME_ERROR("Expected string for baseKind"); continue; } } _Register(kind, baseKind); }
PXR_NAMESPACE_OPEN_SCOPE JsOptionalValue JsFindValue( const JsObject& object, const std::string& key, const JsOptionalValue& defaultValue) { if (key.empty()) { TF_CODING_ERROR("Key is empty"); return boost::none; } JsObject::const_iterator i = object.find(key); if (i != object.end()) return i->second; return defaultValue; }
// This method inspects the JSON blob stored in the 'USD_UserExportedAttributesJson' // attribute on the Maya node at dagPath and exports any attributes specified // there onto usdPrim at time usdTime. The JSON should contain an object that // maps Maya attribute names to other JSON objects that contain metadata about // how to export the attribute into USD. For example: // // { // "myMayaAttributeOne": { // }, // "myMayaAttributeTwo": { // "usdAttrName": "my:namespace:attributeTwo" // } // } // // If the attribute metadata contains a value for "usdAttrName", the attribute // will be given that name in USD. Otherwise, the Maya attribute name will be // used. Maya attributes in the JSON will be processed in sorted order, and any // USD attribute name collisions will be resolved by using the first attribute // visited and warning about subsequent attribute tags. // bool PxrUsdMayaWriteUtil::WriteUserExportedAttributes( const MDagPath& dagPath, const UsdPrim& usdPrim, const UsdTimeCode& usdTime) { MStatus status; MFnDependencyNode depFn(dagPath.node()); MPlug exportedAttrsJsonPlug = depFn.findPlug( _tokens->USD_UserExportedAttributesJson.GetText(), true, &status); if (status != MS::kSuccess || exportedAttrsJsonPlug.isNull()) { // No attributes specified for export on this node. return false; } std::string exportedAttrsJsonString(exportedAttrsJsonPlug.asString().asChar()); if (exportedAttrsJsonString.empty()) { return false; } JsParseError jsError; JsValue jsValue = JsParseString(exportedAttrsJsonString, &jsError); if (not jsValue) { MString errorMsg(TfStringPrintf( "Failed to parse USD exported attributes JSON on node at dagPath '%s'" " at line %d, column %d: %s", dagPath.fullPathName().asChar(), jsError.line, jsError.column, jsError.reason.c_str()).c_str()); MGlobal::displayError(errorMsg); return false; } // Maintain a set of USD attribute names that have been processed. If an // attribute is multiply-defined, we'll use the first tag encountered and // issue warnings for the subsequent definitions. JsObject is really just a // std::map, so we'll be considering attributes in sorted order. std::set<std::string> exportedUsdAttrNames; JsObject exportedAttrs = jsValue.GetObject(); for (JsObject::const_iterator iter = exportedAttrs.begin(); iter != exportedAttrs.end(); ++iter) { const std::string mayaAttrName = iter->first; const MPlug attrPlug = depFn.findPlug(mayaAttrName.c_str(), true, &status); if (status != MS::kSuccess || attrPlug.isNull()) { MString errorMsg(TfStringPrintf( "Could not find attribute '%s' for USD export on node at dagPath '%s'", mayaAttrName.c_str(), dagPath.fullPathName().asChar()).c_str()); MGlobal::displayError(errorMsg); continue; } const JsObject attrMetadata = iter->second.GetObject(); // Check the metadata to see if the USD attribute name should be // different than the Maya attribute name. std::string usdAttrName = mayaAttrName; JsObject::const_iterator usdAttrValueIter = attrMetadata.find(_tokens->usdAttrName); if (usdAttrValueIter != attrMetadata.end()) { std::string nameValue = usdAttrValueIter->second.GetString(); if (not nameValue.empty()) { usdAttrName = nameValue; } } const auto& insertIter = exportedUsdAttrNames.insert(usdAttrName); if (not insertIter.second) { MString errorMsg(TfStringPrintf( "Ignoring duplicate USD export tag for attribute '%s' on node at dagPath '%s'", usdAttrName.c_str(), dagPath.fullPathName().asChar()).c_str()); MGlobal::displayError(errorMsg); continue; } UsdAttribute usdAttr = PxrUsdMayaWriteUtil::GetOrCreateUsdAttr( attrPlug, usdPrim, usdAttrName, true); if (usdAttr) { PxrUsdMayaWriteUtil::SetUsdAttr(attrPlug, usdAttr, usdTime); } } return true; }