Exemple #1
0
UsdAttribute
PxrUsdMayaWriteUtil::GetOrCreateUsdAttr(
    const MPlug& plg,
    const UsdPrim& usdPrim,
    const std::string &attrName,
    bool custom)
{
    MObject attrObj(plg.attribute());

    TfToken usdAttrName(attrName);
    if (usdAttrName.IsEmpty()) {
        printf("Invalid attrName '%s' for %s\n",
               attrName.c_str(),
               plg.name().asChar());
        return UsdAttribute();
    }

    // See if usdAttr already exists.  If so, return.
    UsdAttribute usdAttr = usdPrim.GetAttribute(usdAttrName);
    if (usdAttr) {
        return usdAttr;
    }

    SdfValueTypeName attrType = PxrUsdMayaWriteUtil::GetUsdTypeName(plg);

    // ---------------------
    // CreateAttribute on USD Prim if specified above
    if (attrType) {
        usdAttr = usdPrim.CreateAttribute(usdAttrName, attrType, custom);
    }
    else {
        // Skipping.  Unsupported type.
    }
    return usdAttr;
}
Exemple #2
0
/* static */
UsdAttribute PxrUsdMayaWriteUtil::GetOrCreateUsdRiAttribute(
        const MPlug& attrPlug,
        const UsdPrim& usdPrim,
        const std::string& attrName,
        const std::string& nameSpace,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    UsdAttribute usdAttr;

    if (!usdPrim) {
        return usdAttr;
    }

    MObject attrObj(attrPlug.attribute());

    TfToken riAttrNameToken(attrName);
    if (riAttrNameToken.IsEmpty()) {
        MGlobal::displayError(
            TfStringPrintf("Invalid UsdRi attribute name '%s' for Maya plug '%s'",
                           attrName.c_str(),
                           attrPlug.name().asChar()).c_str());
        return usdAttr;
    }

    UsdRiStatements riStatements(usdPrim);
    if (!riStatements) {
        return usdAttr;
    }

    // See if a UsdRi attribute with this name already exists. If so, return it.
    // XXX: There isn't currently API for looking for a specific UsdRi attribute
    // by name, so we have to get them all and then see if one matches.
    const std::vector<UsdProperty>& riAttrs = riStatements.GetRiAttributes(nameSpace);
    TF_FOR_ALL(iter, riAttrs) {
        if (iter->GetBaseName() == riAttrNameToken) {
            // Re-get the attribute from the prim so we can return it as a
            // UsdAttribute rather than a UsdProperty.
            return usdPrim.GetAttribute(iter->GetName());
        }
    }

    const SdfValueTypeName& typeName =
        PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug,
                                            translateMayaDoubleToUsdSinglePrecision);
    if (typeName) {
        usdAttr = riStatements.CreateRiAttribute(riAttrNameToken,
                                                 typeName.GetType(),
                                                 nameSpace);
    }

    return usdAttr;
}
Exemple #3
0
/* static */
UsdGeomPrimvar PxrUsdMayaWriteUtil::GetOrCreatePrimvar(
        const MPlug& attrPlug,
        UsdGeomImageable& imageable,
        const std::string& primvarName,
        const TfToken& interpolation,
        const int elementSize,
        const bool custom,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    UsdGeomPrimvar primvar;

    if (!imageable) {
        return primvar;
    }

    MObject attrObj(attrPlug.attribute());

    TfToken primvarNameToken(primvarName);
    if (primvarNameToken.IsEmpty()) {
        MGlobal::displayError(
            TfStringPrintf("Invalid primvar name '%s' for Maya plug '%s'",
                           primvarName.c_str(),
                           attrPlug.name().asChar()).c_str());
        return primvar;
    }

    // See if the primvar already exists. If so, return it.
    primvar = imageable.GetPrimvar(primvarNameToken);
    if (primvar) {
        return primvar;
    }

    const SdfValueTypeName& typeName =
        PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug,
                                            translateMayaDoubleToUsdSinglePrecision);
    if (typeName) {
        primvar = imageable.CreatePrimvar(primvarNameToken,
                                          typeName,
                                          interpolation,
                                          elementSize,
                                          custom);
    }

    return primvar;
}
Exemple #4
0
PXR_NAMESPACE_OPEN_SCOPE



static
bool
_GetMayaAttributeNumericTypedAndUnitDataTypes(
        const MPlug& attrPlug,
        MFnNumericData::Type& numericDataType,
        MFnData::Type& typedDataType,
        MFnUnitAttribute::Type& unitDataType)
{
    numericDataType = MFnNumericData::kInvalid;
    typedDataType = MFnData::kInvalid;
    unitDataType = MFnUnitAttribute::kInvalid;

    MObject attrObj(attrPlug.attribute());
    if (attrObj.isNull()) {
        return false;
    }

    if (attrObj.hasFn(MFn::kNumericAttribute)) {
        MFnNumericAttribute numericAttrFn(attrObj);
        numericDataType = numericAttrFn.unitType();
    } else if (attrObj.hasFn(MFn::kTypedAttribute)) {
        MFnTypedAttribute typedAttrFn(attrObj);
        typedDataType = typedAttrFn.attrType();

        if (typedDataType == MFnData::kNumeric) {
            // Inspect the type of the data itself to find the actual type.
            MObject plugObj = attrPlug.asMObject();
            if (plugObj.hasFn(MFn::kNumericData)) {
                MFnNumericData numericDataFn(plugObj);
                numericDataType = numericDataFn.numericType();
            }
        }
    } else if (attrObj.hasFn(MFn::kUnitAttribute)) {
        MFnUnitAttribute unitAttrFn(attrObj);
        unitDataType = unitAttrFn.unitType();
    }

    return true;
}
Exemple #5
0
/* static */
UsdAttribute
PxrUsdMayaWriteUtil::GetOrCreateUsdAttr(
        const MPlug& attrPlug,
        const UsdPrim& usdPrim,
        const std::string& attrName,
        const bool custom,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    UsdAttribute usdAttr;

    if (!usdPrim) {
        return usdAttr;
    }

    MObject attrObj(attrPlug.attribute());

    TfToken usdAttrNameToken(attrName);
    if (usdAttrNameToken.IsEmpty()) {
        MGlobal::displayError(
            TfStringPrintf("Invalid USD attribute name '%s' for Maya plug '%s'",
                           attrName.c_str(),
                           attrPlug.name().asChar()).c_str());
        return usdAttr;
    }

    // See if the USD attribute already exists. If so, return it.
    usdAttr = usdPrim.GetAttribute(usdAttrNameToken);
    if (usdAttr) {
        return usdAttr;
    }

    const SdfValueTypeName& typeName =
        PxrUsdMayaWriteUtil::GetUsdTypeName(attrPlug,
                                            translateMayaDoubleToUsdSinglePrecision);
    if (typeName) {
        usdAttr = usdPrim.CreateAttribute(usdAttrNameToken, typeName, custom);
    }

    return usdAttr;
}
Exemple #6
0
bool
PxrUsdMayaWriteUtil::SetUsdAttr(
        const MPlug& attrPlug,
        const UsdAttribute& usdAttr,
        const UsdTimeCode& usdTime,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    if (!usdAttr || attrPlug.isNull()) {
        return false;
    }

    bool isAnimated = attrPlug.isDestination();
    if (usdTime.IsDefault() == isAnimated) {
        return true;
    }

    // We perform a similar set of type-infererence acrobatics here as we do up
    // above in GetUsdTypeName(). See the comments there for more detail on a
    // few type-related oddities.

    MObject attrObj(attrPlug.attribute());

    if (attrObj.hasFn(MFn::kEnumAttribute)) {
        MFnEnumAttribute enumAttrFn(attrObj);
        const short enumIndex = attrPlug.asShort();
        const TfToken enumToken(enumAttrFn.fieldName(enumIndex).asChar());
        return usdAttr.Set(enumToken, usdTime);
    }

    MFnNumericData::Type numericDataType;
    MFnData::Type typedDataType;
    MFnUnitAttribute::Type unitDataType;

    _GetMayaAttributeNumericTypedAndUnitDataTypes(attrPlug,
                                                  numericDataType,
                                                  typedDataType,
                                                  unitDataType);

    if (attrObj.hasFn(MFn::kMatrixAttribute)) {
        typedDataType = MFnData::kMatrix;
    }

    switch (typedDataType) {
        case MFnData::kString: {
            MFnStringData stringDataFn(attrPlug.asMObject());
            const std::string usdVal(stringDataFn.string().asChar());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kMatrix: {
            MFnMatrixData matrixDataFn(attrPlug.asMObject());
            const GfMatrix4d usdVal(matrixDataFn.matrix().matrix);
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kStringArray: {
            MFnStringArrayData stringArrayDataFn(attrPlug.asMObject());
            VtStringArray usdVal(stringArrayDataFn.length());
            for (unsigned int i = 0; i < stringArrayDataFn.length(); ++i) {
                usdVal[i] = std::string(stringArrayDataFn[i].asChar());
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kDoubleArray: {
            MFnDoubleArrayData doubleArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtFloatArray usdVal(doubleArrayDataFn.length());
                for (unsigned int i = 0; i < doubleArrayDataFn.length(); ++i) {
                    usdVal[i] = (float)doubleArrayDataFn[i];
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtDoubleArray usdVal(doubleArrayDataFn.length());
                for (unsigned int i = 0; i < doubleArrayDataFn.length(); ++i) {
                    usdVal[i] = doubleArrayDataFn[i];
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnData::kFloatArray: {
            MFnFloatArrayData floatArrayDataFn(attrPlug.asMObject());
            VtFloatArray usdVal(floatArrayDataFn.length());
            for (unsigned int i = 0; i < floatArrayDataFn.length(); ++i) {
                usdVal[i] = floatArrayDataFn[i];
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kIntArray: {
            MFnIntArrayData intArrayDataFn(attrPlug.asMObject());
            VtIntArray usdVal(intArrayDataFn.length());
            for (unsigned int i = 0; i < intArrayDataFn.length(); ++i) {
                usdVal[i] = intArrayDataFn[i];
            }
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnData::kPointArray: {
            MFnPointArrayData pointArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtVec3fArray usdVal(pointArrayDataFn.length());
                for (unsigned int i = 0; i < pointArrayDataFn.length(); ++i) {
                    MPoint tmpMayaVal = pointArrayDataFn[i];
                    if (tmpMayaVal.w != 0) {
                        tmpMayaVal.cartesianize();
                    }
                    usdVal[i] = GfVec3f((float)tmpMayaVal[0],
                                        (float)tmpMayaVal[1],
                                        (float)tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtVec3dArray usdVal(pointArrayDataFn.length());
                for (unsigned int i = 0; i < pointArrayDataFn.length(); ++i) {
                    MPoint tmpMayaVal = pointArrayDataFn[i];
                    if (tmpMayaVal.w != 0) {
                        tmpMayaVal.cartesianize();
                    }
                    usdVal[i] = GfVec3d(tmpMayaVal[0],
                                        tmpMayaVal[1],
                                        tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnData::kVectorArray: {
            MFnVectorArrayData vectorArrayDataFn(attrPlug.asMObject());
            if (translateMayaDoubleToUsdSinglePrecision) {
                VtVec3fArray usdVal(vectorArrayDataFn.length());
                for (unsigned int i = 0; i < vectorArrayDataFn.length(); ++i) {
                    MVector tmpMayaVal = vectorArrayDataFn[i];
                    usdVal[i] = GfVec3f((float)tmpMayaVal[0],
                                        (float)tmpMayaVal[1],
                                        (float)tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            } else {
                VtVec3dArray usdVal(vectorArrayDataFn.length());
                for (unsigned int i = 0; i < vectorArrayDataFn.length(); ++i) {
                    MVector tmpMayaVal = vectorArrayDataFn[i];
                    usdVal[i] = GfVec3d(tmpMayaVal[0],
                                        tmpMayaVal[1],
                                        tmpMayaVal[2]);
                }
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        default:
            break;
    }

    switch (numericDataType) {
        case MFnNumericData::kBoolean: {
            const bool usdVal(attrPlug.asBool());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kByte:
        case MFnNumericData::kChar: {
            const int usdVal(attrPlug.asChar());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kShort: {
            const int usdVal(attrPlug.asShort());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::kInt: {
            const int usdVal(attrPlug.asInt());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::k2Short: {
            short tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k2Int: {
            int tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2i(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Short: {
            short tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::k3Int: {
            int tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return usdAttr.Set(GfVec3i(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::kFloat: {
            const float usdVal(attrPlug.asFloat());
            return usdAttr.Set(usdVal, usdTime);
            break;
        }
        case MFnNumericData::k2Float: {
            float tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            return usdAttr.Set(GfVec2f(tmp1, tmp2), usdTime);
            break;
        }
        case MFnNumericData::k3Float: {
            float tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            return _SetVec(usdAttr, GfVec3f(tmp1, tmp2, tmp3), usdTime);
            break;
        }
        case MFnNumericData::kDouble: {
            const double usdVal(attrPlug.asDouble());
            if (translateMayaDoubleToUsdSinglePrecision) {
                return usdAttr.Set((float)usdVal, usdTime);
            } else {
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        }
        case MFnNumericData::k2Double: {
            double tmp1, tmp2;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return usdAttr.Set(GfVec2f((float)tmp1, (float)tmp2), usdTime);
            } else {
                return usdAttr.Set(GfVec2d(tmp1, tmp2), usdTime);
            }
            break;
        }
        case MFnNumericData::k3Double: {
            double tmp1, tmp2, tmp3;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return _SetVec(usdAttr,
                               GfVec3f((float)tmp1,
                                       (float)tmp2,
                                       (float)tmp3),
                               usdTime);
            } else {
                return _SetVec(usdAttr, GfVec3d(tmp1, tmp2, tmp3), usdTime);
            }
            break;
        }
        case MFnNumericData::k4Double: {
            double tmp1, tmp2, tmp3, tmp4;
            MFnNumericData numericDataFn(attrPlug.asMObject());
            numericDataFn.getData(tmp1, tmp2, tmp3, tmp4);
            if (translateMayaDoubleToUsdSinglePrecision) {
                return _SetVec(usdAttr,
                               GfVec4f((float)tmp1,
                                       (float)tmp2,
                                       (float)tmp3,
                                       (float)tmp4),
                               usdTime);
            } else {
                return _SetVec(usdAttr,
                               GfVec4d(tmp1, tmp2, tmp3, tmp4),
                               usdTime);
            }
            break;
        }
        default:
            break;
    }

    switch (unitDataType) {
        case MFnUnitAttribute::kAngle:
        case MFnUnitAttribute::kDistance:
            if (translateMayaDoubleToUsdSinglePrecision) {
                const float usdVal(attrPlug.asFloat());
                return usdAttr.Set(usdVal, usdTime);
            } else {
                const double usdVal(attrPlug.asDouble());
                return usdAttr.Set(usdVal, usdTime);
            }
            break;
        default:
            break;
    }

    return false;
}
Exemple #7
0
SdfValueTypeName
PxrUsdMayaWriteUtil::GetUsdTypeName(
        const MPlug& attrPlug,
        const bool translateMayaDoubleToUsdSinglePrecision)
{
    // The various types of Maya attributes that can be created are spread
    // across a handful of MFn function sets. Some are a straightforward
    // translation such as MFnEnumAttributes or MFnMatrixAttributes, but others
    // are interesting mixes of function sets. For example, an attribute created
    // with addAttr and 'double' as the type results in an MFnNumericAttribute
    // while 'double2' as the type results in an MFnTypedAttribute that has
    // MFnData::Type kNumeric.

    MObject attrObj(attrPlug.attribute());
    if (attrObj.isNull()) {
        return SdfValueTypeName();
    }

    if (attrObj.hasFn(MFn::kEnumAttribute)) {
        return SdfValueTypeNames->Token;
    }

    MFnNumericData::Type numericDataType;
    MFnData::Type typedDataType;
    MFnUnitAttribute::Type unitDataType;

    _GetMayaAttributeNumericTypedAndUnitDataTypes(attrPlug,
                                                  numericDataType,
                                                  typedDataType,
                                                  unitDataType);

    if (attrObj.hasFn(MFn::kMatrixAttribute)) {
        // Using type "fltMatrix" with addAttr results in an MFnMatrixAttribute
        // while using type "matrix" results in an MFnTypedAttribute with type
        // kMatrix, but the data is extracted the same way for both.
        typedDataType = MFnData::kMatrix;
    }

    // Deal with the MFnTypedAttribute attributes first. If it is numeric, it
    // will fall through to the numericDataType switch below.
    switch (typedDataType) {
        case MFnData::kString:
            return SdfValueTypeNames->String;
            break;
        case MFnData::kMatrix:
            // This must be a Matrix4d even if
            // translateMayaDoubleToUsdSinglePrecision is true, since Matrix4f
            // is not supported in Sdf.
            return SdfValueTypeNames->Matrix4d;
            break;
        case MFnData::kStringArray:
            return SdfValueTypeNames->StringArray;
            break;
        case MFnData::kDoubleArray:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->FloatArray;
            } else {
                return SdfValueTypeNames->DoubleArray;
            }
            break;
        case MFnData::kFloatArray:
            return SdfValueTypeNames->FloatArray;
            break;
        case MFnData::kIntArray:
            return SdfValueTypeNames->IntArray;
            break;
        case MFnData::kPointArray:
            // Sdf does not have a 4-float point type, so we'll divide out W
            // and export the points as 3 floats.
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Point3fArray;
            } else {
                return SdfValueTypeNames->Point3dArray;
            }
            break;
        case MFnData::kVectorArray:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Vector3fArray;
            } else {
                return SdfValueTypeNames->Vector3dArray;
            }
            break;
        default:
            break;
    }

    switch (numericDataType) {
        case MFnNumericData::kBoolean:
            return SdfValueTypeNames->Bool;
            break;
        case MFnNumericData::kByte:
        case MFnNumericData::kChar:
        case MFnNumericData::kShort:
        // Maya treats longs the same as ints, since long is not
        // platform-consistent. The Maya constants MFnNumericData::kInt and
        // MFnNumericData::kLong have the same value. The same is true of
        // k2Int/k2Long and k3Int/k3Long.
        case MFnNumericData::kInt:
            return SdfValueTypeNames->Int;
            break;
        case MFnNumericData::k2Short:
        case MFnNumericData::k2Int:
            return SdfValueTypeNames->Int2;
            break;
        case MFnNumericData::k3Short:
        case MFnNumericData::k3Int:
            return SdfValueTypeNames->Int3;
            break;
        case MFnNumericData::kFloat:
            return SdfValueTypeNames->Float;
            break;
        case MFnNumericData::k2Float:
            return SdfValueTypeNames->Float2;
            break;
        case MFnNumericData::k3Float:
            if (MFnAttribute(attrObj).isUsedAsColor()) {
                return SdfValueTypeNames->Color3f;
            } else {
                return SdfValueTypeNames->Float3;
            }
            break;
        case MFnNumericData::kDouble:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Float;
            } else {
                return SdfValueTypeNames->Double;
            }
            break;
        case MFnNumericData::k2Double:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Float2;
            } else {
                return SdfValueTypeNames->Double2;
            }
            break;
        case MFnNumericData::k3Double:
            if (MFnAttribute(attrObj).isUsedAsColor()) {
                if (translateMayaDoubleToUsdSinglePrecision) {
                    return SdfValueTypeNames->Color3f;
                } else {
                    return SdfValueTypeNames->Color3d;
                }
            } else {
                if (translateMayaDoubleToUsdSinglePrecision) {
                    return SdfValueTypeNames->Float3;
                } else {
                    return SdfValueTypeNames->Double3;
                }
            }
            break;
        case MFnNumericData::k4Double:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Float4;
            } else {
                return SdfValueTypeNames->Double4;
            }
            break;
        default:
            break;
    }

    switch (unitDataType) {
        case MFnUnitAttribute::kAngle:
        case MFnUnitAttribute::kDistance:
            if (translateMayaDoubleToUsdSinglePrecision) {
                return SdfValueTypeNames->Float;
            } else {
                return SdfValueTypeNames->Double;
            }
            break;
        default:
            break;
    }

    return SdfValueTypeName();
}
Exemple #8
0
SdfValueTypeName
PxrUsdMayaWriteUtil::GetUsdTypeName( const MPlug& plg)
{
    MObject attrObj(plg.attribute());

    SdfValueTypeName attrType;
    if (attrObj.hasFn(MFn::kNumericAttribute)) {
        MFnNumericAttribute attrNumericFn(attrObj);
        switch (attrNumericFn.unitType())
        {
        case MFnNumericData::kBoolean:
            attrType = SdfValueTypeNames->Bool;
            break;
        case MFnNumericData::kByte:
        case MFnNumericData::kChar:
        case MFnNumericData::kShort:
        case MFnNumericData::kInt:
            attrType = SdfValueTypeNames->Int;
            break;
        /* We could do these, but there doesn't seem to be a good way of extracting
           the data later on.  For a Maya expert to solve...
                case MFnNumericData::kLong:
                    attrType = SdfValueTypeNames->Int64;
                    break;
                case MFnNumericData::kAddr:
                    attrType = SdfValueTypeNames->UInt64;
                    break;
        */
        case MFnNumericData::kFloat:
            attrType = SdfValueTypeNames->Float;
            break;
        case MFnNumericData::kDouble:
            attrType = SdfValueTypeNames->Double;
            break;
        case MFnNumericData::k2Short:
        case MFnNumericData::k2Int:
            //case MFnNumericData::k2Long:
            attrType = SdfValueTypeNames->Int2;
            break;
        case MFnNumericData::k3Short:
        case MFnNumericData::k3Int:
            //case MFnNumericData::k3Long:
            attrType = SdfValueTypeNames->Int3;
            break;
        case MFnNumericData::k2Float:
            attrType = SdfValueTypeNames->Float2;
            break;
        case MFnNumericData::k3Float:
            if (MFnAttribute(attrObj).isUsedAsColor()) {
                attrType = SdfValueTypeNames->Color3f;
            }
            else {
                attrType = SdfValueTypeNames->Float3;
            }
            break;
        case MFnNumericData::k2Double:
            attrType = SdfValueTypeNames->Double2;
            break;
        case MFnNumericData::k3Double:
            if (MFnAttribute(attrObj).isUsedAsColor()) {
                attrType = SdfValueTypeNames->Color3d;
            }
            else {
                attrType = SdfValueTypeNames->Double3;
            }
            break;
        case MFnNumericData::k4Double:
            attrType = SdfValueTypeNames->Double4;
            break;
        default:
            break;
        }
    }
    else if (attrObj.hasFn(MFn::kTypedAttribute)) {
        MFnTypedAttribute attrTypedFn(attrObj);
        switch (attrTypedFn.attrType())
        {
        case MFnData::kString:
            attrType = SdfValueTypeNames->String;
            break;
        case MFnData::kMatrix:
            attrType = SdfValueTypeNames->Matrix4d;
            break;
        case MFnData::kStringArray:
            attrType = SdfValueTypeNames->StringArray;
            break;
        case MFnData::kIntArray:
            attrType = SdfValueTypeNames->IntArray;
            break;
        case MFnData::kFloatArray:
            attrType = SdfValueTypeNames->FloatArray;
            break;
        case MFnData::kDoubleArray:
            attrType = SdfValueTypeNames->DoubleArray;
            break;
        case MFnData::kVectorArray:
            attrType = SdfValueTypeNames->Vector3dArray;
            break;
        case MFnData::kPointArray:
            attrType = SdfValueTypeNames->Point3dArray;
            break;
        default:
            break;
        }
    }
    else if (attrObj.hasFn(MFn::kUnitAttribute)) {
        //MFnUnitAttribute attrUnitFn(attrObj);
    }
    else if (attrObj.hasFn(MFn::kEnumAttribute)) {
        attrType = SdfValueTypeNames->Token;
    }

    return attrType;
}