Exemplo n.º 1
0
int main(int argc, char const *argv[])
{
    if (argc != 3) {
        fprintf(stderr, "Usage: %s inputFile outputFile\n", argv[0]);
        return 1;
    }

    std::ifstream ifs(argv[1]);
    if (not ifs) {
        fprintf(stderr, "Error: failed to open input file '%s'", argv[1]);
        return 2;
    }

    JsParseError error;
    const JsValue value = JsParseStream(ifs, &error);

    if (value.IsNull()) {
        fprintf(stderr, "Error: parse error at %s:%d:%d: %s\n",
            argv[1], error.line, error.column, error.reason.c_str());
        return 2;
    }

    if (argv[2][0] == '-') {
        JsWriteToStream(value, std::cout);
    } else {
        std::ofstream ofs(argv[2]);
        if (not ofs) {
            fprintf(stderr, "Error: failed to open output file '%s'", argv[2]);
            return 2;
        }
        JsWriteToStream(value, ofs);
    }

    return 0;
}
Exemplo n.º 2
0
Arquivo: json.cpp Projeto: JT-a/USD
static rj::Value
_JsValueToImplValue(
    const JsValue& value,
    Allocator& allocator)
{
    switch (value.GetType()) {
    case JsValue::ObjectType:
        return _ToImplObjectValue(value.GetJsObject(), allocator);
    case JsValue::ArrayType:
        return _ToImplArrayValue(value.GetJsArray(), allocator);
    case JsValue::BoolType:
        return rj::Value(value.GetBool());
    case JsValue::StringType:
        return rj::Value(value.GetString().c_str(), allocator);
    case JsValue::RealType:
        return rj::Value(value.GetReal());
    case JsValue::IntType:
        return value.IsUInt64() ?
            rj::Value(value.GetUInt64()) : rj::Value(value.GetInt64());
    case JsValue::NullType:
        return rj::Value();
    default: {
        TF_CODING_ERROR("Unknown JsValue type");
        return rj::Value();
        }
    }
}
Exemplo n.º 3
0
static bool
_ReadNestedDict(
        const JsObject& data,
        const std::vector<TfToken>& keys,
        JsObject* dict)
{
    JsObject currDict = data;
    TF_FOR_ALL(iter, keys) {
        const TfToken& currKey = *iter;
        JsValue any;
        if (!TfMapLookup(currDict, currKey, &any)) {
            return false;
        }

        if (!any.IsObject()) {
            TF_CODING_ERROR("bad plugInfo data.");
            return false;
        }
        currDict = any.GetJsObject();
    }
    *dict = currDict;
    return true;
}
Exemplo n.º 4
0
static void
_CheckArrayOf(
    const JsValue& value)
{
    IndenterScope scope(*indenter);

    TF_AXIOM(value.IsArrayOf<T>());

    const std::vector<T> array = value.GetArrayOf<T>();
    const JsArray& expArray = value.GetJsArray();

    indent << "array.size = " << array.size()
        << ", expArray.size = " << expArray.size() << std::endl;

    for (size_t i = 0; i < array.size(); ++i) {
        TF_AXIOM(array[i] == expArray[i].Get<T>());
    }    
}
Exemplo n.º 5
0
int main(int argc, char const *argv[])
{
    std::cout << "opening values.json" << std::endl;
    std::ifstream ifs("values.json");
    if (!ifs) {
        TF_CODING_ERROR("Failed to open 'values.json' for reading");
        return 1;
    }

    // Set up expected values.
    std::cout << "parsing input stream" << std::endl;
    const JsValue value = JsParseStream(ifs);
    TF_AXIOM(value);
    TF_AXIOM(value.IsObject());

    std::cout << "unwrapping envelope" << std::endl;
    JsObject envelope = value.GetJsObject();
    TF_AXIOM(envelope["Object"].IsObject());
    JsObject object = envelope["Object"].GetJsObject();
    TF_AXIOM(!object.empty());

    // Convert the top-level value to another container type.
    std::cout << "converting container" << std::endl;
    const _Any result = JsConvertToContainerType<_Any, _Dictionary>(value);
    TF_AXIOM(!IsEmpty(result));
    TF_AXIOM(IsHolding<_Dictionary>(result));

    std::cout << "checking converted top-level object" << std::endl;
    const _Dictionary& dict = Get<_Dictionary>(result);
    _Dictionary::const_iterator i = dict.find("Object");
    TF_AXIOM(i != dict.end());
    TF_AXIOM(IsHolding<_Dictionary>(i->second));
    const _Dictionary& aObject = Get<_Dictionary>(i->second);

    std::cout << "checking converted values" << std::endl;

    for (const auto& p : aObject) {
        const std::type_info* ti = GetType(p.second);
        indent << "key " << p.first << " typeid is " <<
            (ti ? ArchGetDemangled(*ti) : "nil") << std::endl;

        IndenterScope scope(*indenter);

        if (p.first == "Array") {
            indent << "checking array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());

            // This array has heterogeneous values, so IsArrayOf<T> should
            // always return false.
            TF_AXIOM(!object[p.first].IsArrayOf<JsObject>());
            TF_AXIOM(!object[p.first].IsArrayOf<JsArray>());
            TF_AXIOM(!object[p.first].IsArrayOf<string>());
            TF_AXIOM(!object[p.first].IsArrayOf<double>());
            TF_AXIOM(!object[p.first].IsArrayOf<int>());
            TF_AXIOM(!object[p.first].IsArrayOf<int64_t>());
            TF_AXIOM(!object[p.first].IsArrayOf<uint64_t>());

        } else if (p.first == "ArrayString") {
            indent << "checking string array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(object[p.first].Is<JsArray>());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());
            _CheckArrayOf<string>(object[p.first]);
        } else if (p.first == "ArrayInt64") {
            indent << "checking int64 array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(object[p.first].Is<JsArray>());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());
            _CheckArrayOf<int64_t>(object[p.first]);
        } else if (p.first == "ArrayUInt64") {
            indent << "checking uint array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(object[p.first].Is<JsArray>());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());
            _CheckArrayOf<uint64_t>(object[p.first]);
        } else if (p.first == "ArrayReal") {
            indent << "checking real array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(object[p.first].Is<JsArray>());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());
            _CheckArrayOf<double>(object[p.first]);
        } else if (p.first == "ArrayBool") {
            indent << "checking bool array conversion" << std::endl;
            TF_AXIOM(object[p.first].IsArray());
            TF_AXIOM(object[p.first].Is<JsArray>());
            TF_AXIOM(IsHolding<_AnyVector>(p.second));
            _CheckArray(Get<_AnyVector>(p.second), object[p.first].GetJsArray());
            _CheckArray(Get<_AnyVector>(p.second), 
                        object[p.first].Get<JsArray>());
            _CheckArrayOf<bool>(object[p.first]);
        } else if (p.first == "String") {
            indent << "checking string conversion" << std::endl;
            TF_AXIOM(object[p.first].IsString());
            TF_AXIOM(object[p.first].Is<string>());
            TF_AXIOM(IsHolding<string>(p.second));
            TF_AXIOM(Get<string>(p.second) == object[p.first].GetString());
            TF_AXIOM(Get<string>(p.second) == object[p.first].Get<string>());
        } else if (p.first == "Int64") {
            indent << "checking int conversion" << std::endl;
            TF_AXIOM(object[p.first].IsInt());
            TF_AXIOM(object[p.first].Is<int64_t>());
            TF_AXIOM(IsHolding<int64_t>(p.second));
            TF_AXIOM(Get<int64_t>(p.second) == object[p.first].GetInt());
            TF_AXIOM(Get<int64_t>(p.second) == object[p.first].Get<int64_t>());
        } else if (p.first == "UInt64") {
            indent << "checking uint conversion" << std::endl;
            TF_AXIOM(object[p.first].IsInt());
            TF_AXIOM(object[p.first].Is<uint64_t>());
            TF_AXIOM(IsHolding<uint64_t>(p.second));
            TF_AXIOM(Get<uint64_t>(p.second) == static_cast<uint64_t>(object[p.first].GetInt()));
            TF_AXIOM(Get<uint64_t>(p.second) == object[p.first].Get<uint64_t>());
        } else if (p.first == "Real") {
            indent << "checking real conversion" << std::endl;
            TF_AXIOM(object[p.first].IsReal());
            TF_AXIOM(object[p.first].Is<double>());
            TF_AXIOM(IsHolding<double>(p.second));
            TF_AXIOM(Get<double>(p.second) == object[p.first].GetReal());
            TF_AXIOM(Get<double>(p.second) == object[p.first].Get<double>());
        } else if (p.first == "BoolTrue") {
            indent << "checking bool(true) conversion" << std::endl;
            TF_AXIOM(object[p.first].IsBool());
            TF_AXIOM(object[p.first].Is<bool>());
            TF_AXIOM(IsHolding<bool>(p.second));
            TF_AXIOM(Get<bool>(p.second));
            TF_AXIOM(object[p.first].Get<bool>());
        } else if (p.first == "BoolFalse") {
            indent << "checking bool(false) conversion" << std::endl;
            TF_AXIOM(object[p.first].IsBool());
            TF_AXIOM(object[p.first].Is<bool>());
            TF_AXIOM(IsHolding<bool>(p.second));
            TF_AXIOM(!Get<bool>(p.second));
            TF_AXIOM(!object[p.first].Get<bool>());
        } else if (p.first == "Null") {
            indent << "checking null conversion" << std::endl;
            TF_AXIOM(object[p.first].IsNull());
            TF_AXIOM(IsEmpty(p.second));
        }
    }

    std::cout << "PASSED" << std::endl;
    return 0;
}
/* 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;
}
Exemplo n.º 7
0
// 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;
}