/* 相当于把string字符串放置在当前环境下执行. */ static void JsGlobalEval(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res) { int saveVarattr; //检查参数是否正确 if(argc <=0) { res->type =JS_UNDEFINED; return; } else if( argv[0]->type != JS_STRING) { *res = *argv[0]; return; } //从线程中获得JsEngine struct JsEngine* e = JsGetTlsEngine(); //处理上下文 /*Stack, Scope, This 都使用当前Context*/ saveVarattr = e->exec->varattr; e->exec->varattr = JS_OBJECT_ATTR_DEFAULT; //执行函数 res->type =JS_UNDEFINED; struct JsAstNode * ast; ast = JsParseString(e->vm->debug ? JS_PARSER_DEBUG_ERROR : JS_PARSER_DEBUG_CLOSE,argv[0]->u.string); if(ast == NULL) JsThrowString("SytaxError"); JsEval(e,ast,res); //还原环境 e->exec->varattr = saveVarattr; //结果处理 if(res->type == JS_COMPLETION) { if(res->u.completion.type == JS_COMPLETION_RETURN) { *res = *res->u.completion.value; } else if(res->u.completion.type == JS_COMPLETION_THROW) { //不处理 } else { //JS_COMPLETION_NORMAL, JS_COMPLETION_BREAK, JS_COMPLETION_CONTINUE res->type = JS_UNDEFINED; } } else if(res->type == JS_REFERENCE) { res->type = JS_UNDEFINED; }//res->type = JS_OBJECT, JS_NULL, JS_BOOLEAN ... return; }
JsValue JsParseStream( std::istream& istr, JsParseError* error) { if (!istr) { TF_CODING_ERROR("Stream error"); return JsValue(); } // Parse streams by reading into a string first. This makes it easier to // yield good error messages that include line and column numbers, rather // than the character offset that rapidjson currently provides. return JsParseString(std::string( (std::istreambuf_iterator<char>(istr)), std::istreambuf_iterator<char>()), error); }
/* static */ std::vector<UsdMayaUserTaggedAttribute> UsdMayaUserTaggedAttribute::GetUserTaggedAttributesForNode( const MObject& mayaNode) { std::vector<UsdMayaUserTaggedAttribute> result; MStatus status; const MFnDependencyNode depNodeFn(mayaNode, &status); if (status != MS::kSuccess) { return result; } const MPlug exportedAttrsJsonPlug = depNodeFn.findPlug( _tokens->USD_UserExportedAttributesJson.GetText(), true, &status); if (status != MS::kSuccess || exportedAttrsJsonPlug.isNull()) { // No attributes specified for export on this node. return result; } const std::string exportedAttrsJsonString( exportedAttrsJsonPlug.asString().asChar()); if (exportedAttrsJsonString.empty()) { return result; } JsParseError jsError; const JsValue jsValue = JsParseString(exportedAttrsJsonString, &jsError); if (!jsValue) { TF_RUNTIME_ERROR( "Failed to parse USD exported attributes JSON on node '%s' " "at line %d, column %d: %s", UsdMayaUtil::GetMayaNodeName(mayaNode).c_str(), jsError.line, jsError.column, jsError.reason.c_str()); return result; } // 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> processedAttributeNames; const JsObject& exportedAttrs = jsValue.GetJsObject(); for (const auto& exportedAttr : exportedAttrs) { const std::string mayaAttrName = exportedAttr.first; const MPlug attrPlug = depNodeFn.findPlug(mayaAttrName.c_str(), true, &status); if (status != MS::kSuccess || attrPlug.isNull()) { TF_RUNTIME_ERROR( "Could not find attribute '%s' for USD export on node '%s'", mayaAttrName.c_str(), UsdMayaUtil::GetMayaNodeName(mayaNode).c_str()); continue; } const JsObject& attrMetadata = exportedAttr.second.GetJsObject(); // Check if this is a particular type of attribute (e.g. primvar or // usdRi attribute). If we don't recognize the type specified, we'll // fall back to a regular USD attribute. const TfToken usdAttrType( _GetExportAttributeMetadata(attrMetadata, _tokens->usdAttrType)); // Check whether an interpolation type was specified. This is only // relevant for primvars. const TfToken interpolation( _GetExportAttributeMetadata(attrMetadata, UsdGeomTokens->interpolation)); // Check whether it was specified that the double precision Maya // attribute type should be mapped to a single precision USD type. // If it wasn't specified, use the fallback value. const bool translateMayaDoubleToUsdSinglePrecision( _GetExportAttributeMetadata( attrMetadata, _tokens->translateMayaDoubleToUsdSinglePrecision, GetFallbackTranslateMayaDoubleToUsdSinglePrecision())); // Check whether the USD attribute name should be different than the // Maya attribute name. std::string usdAttrName = _GetExportAttributeMetadata(attrMetadata, _tokens->usdAttrName); if (usdAttrName.empty()) { const auto& tokens = UsdMayaUserTaggedAttributeTokens; if (usdAttrType == tokens->USDAttrTypePrimvar || usdAttrType == tokens->USDAttrTypeUsdRi) { // Primvars and UsdRi attributes will be given a type-specific // namespace, so just use the Maya attribute name. usdAttrName = mayaAttrName; } else { // For regular USD attributes, when no name was specified we // prepend the userProperties namespace to the Maya attribute // name to get the USD attribute name. usdAttrName = _tokens->UserPropertiesNamespace.GetString() + mayaAttrName; } } const auto& insertIter = processedAttributeNames.emplace(usdAttrName); if (!insertIter.second) { TF_RUNTIME_ERROR( "Ignoring duplicate USD export tag for attribute '%s' " "on node '%s'", usdAttrName.c_str(), UsdMayaUtil::GetMayaNodeName(mayaNode).c_str()); continue; } result.emplace_back(attrPlug, usdAttrName, usdAttrType, interpolation, translateMayaDoubleToUsdSinglePrecision); } return result; }
// 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; }