#include "AttributesWriter.h"
#include "MayaUtility.h"
namespace Abc = Alembic::Abc;
namespace AbcGeom = Alembic::AbcGeom;
namespace AbcA = Alembic::AbcCoreAbstract;
namespace {
static const char * cAttrScope = "_AbcGeomScope";
static const char * cAttrType  = "_AbcType";
bool isDataAttr(
const MPlug & iParent)
 
{
    {
            return true;
        default:
            return false;
    }
}
AbcGeom::GeometryScope strToScope(
MString iStr)
{
    if (iStr == "vtx")
    {
        return AbcGeom::kVertexScope;
    }
    else if (iStr == "fvr")
    {
        return AbcGeom::kFacevaryingScope;
    }
    else if (iStr == "uni")
    {
        return AbcGeom::kUniformScope;
    }
    else if (iStr == "var")
    {
        return AbcGeom::kVaryingScope;
    }
    return AbcGeom::kConstantScope;
}
bool endsWithArbAttr(const std::string & iStr)
{
    size_t len = iStr.size();
    return (len >= 13 && iStr.compare(len - 13, 13, cAttrScope) == 0) ||
        (len >= 8 && iStr.compare(len - 8, 8, cAttrType) == 0);
}
                                   Abc::OCompoundProperty & iParent,
                                   Alembic::Util::uint32_t iTimeIndex,
                                   AbcGeom::GeometryScope iScope,
                                   std::vector < PlugAndObjScalar > & oScalars,
                                   std::vector < PlugAndObjArray > & oArrays)
{
    switch (iType)
    {
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OBoolProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OCharProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OInt16Property up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OInt32Property up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OFloatProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::ODoubleProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV2sProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV3sProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV2iProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV3iProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV2fProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV3fProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV2dProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjScalar p;
            p.plug = iPlug;
            p.obj = iAttr;
            Abc::OV3dProperty up(iParent, plugName, iTimeIndex);
            p.prop = up;
            oScalars.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcA::DataType dtype(Alembic::Util::kFloat64POD, 4);
            Abc::OArrayProperty up(iParent, plugName, dtype, iTimeIndex);
            p.prop = up;
            oArrays.push_back(p);
        }
        break;
        default:
        break;
    }
}
                               const MPlug& iPlug, Abc::OCompoundProperty & iParent,
 
                               Alembic::Util::uint32_t iTimeIndex,
                               AbcGeom::GeometryScope iScope,
                               std::vector < PlugAndObjArray > & oArrayVec)
{
    switch (iType)
    {
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OBoolGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OCharGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OInt16GeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OInt32GeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OFloatGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::ODoubleGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV2sGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV3sGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV2iGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV3iGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV2fGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            {
                AbcGeom::OC3fGeomParam gp(iParent, plugName, false, iScope, 1,
                    iTimeIndex);
                p.prop = gp.getValueProperty();
            }
            else
            {
                AbcGeom::OV3fGeomParam gp(iParent, plugName, false, iScope, 1,
                    iTimeIndex);
                p.prop = gp.getValueProperty();
            }
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV2dGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcGeom::OV3dGeomParam gp(iParent, plugName, false, iScope, 1,
                iTimeIndex);
            p.prop = gp.getValueProperty();
            oArrayVec.push_back(p);
        }
        break;
        {
            PlugAndObjArray p;
            p.plug = iPlug;
            p.obj = iAttr;
            AbcA::DataType dtype(Alembic::Util::kFloat64POD, 4);
            p.prop = Abc::OArrayProperty(iParent, plugName, dtype, iTimeIndex);
            oArrayVec.push_back(p);
        }
        break;
        default:
        break;
    }
}
                            Abc::OScalarProperty & oProp)
{
    int    ival;
    float  fval;
    double dval;
    bool   bval;
    Alembic::Util::int16_t sval;
    Alembic::Util::int8_t  cval;
    Alembic::Util::int16_t v2sVal[2];
    Alembic::Util::int16_t v3sVal[3];
    Alembic::Util::int32_t v2iVal[2];
    Alembic::Util::int32_t v3iVal[3];
    float v2fVal[2];
    float v3fVal[3];
    double v2dVal[2];
    double v3dVal[3];
    switch (iType)
    {
        {
            oProp.set(&bval);
        }
        break;
        {
            oProp.set(&cval);
        }
        break;
        {
            oProp.set(&sval);
        }
        break;
        {
            oProp.set(&ival);
        }
        break;
        {
            oProp.set(&fval);
        }
        break;
        {
            oProp.set(&dval);
        }
        break;
        {
        }
        break;
        {
        }
        break;
        {
            int val0, val1;
            v2iVal[0] = Alembic::Util::int32_t(val0);
            v2iVal[1] = Alembic::Util::int32_t(val1);
            oProp.set(&v2iVal[0]);
        }
        break;
        {
            int val0, val1, val2;
            v3iVal[0] = Alembic::Util::int32_t(val0);
            v3iVal[1] = Alembic::Util::int32_t(val1);
            v3iVal[2] = Alembic::Util::int32_t(val2);
            oProp.set(&v3iVal[0]);
        }
        break;
        {
        }
        break;
        {
        }
        break;
        {
        }
        break;
        {
        }
        break;
        default:
            return false;
        break;
    }
    return true;
}
                            Abc::OArrayProperty & oProp)
{
    unsigned int dimSize = numElements;
    if (!isArray)
        dimSize = 1;
    switch (iType)
    {
        {
            std::vector< Alembic::Util::bool_t > val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector< Alembic::Util::int8_t > val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector< Alembic::Util::int16_t > val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector< Alembic::Util::int32_t > val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                    val[i] = iPlug[i].
asInt();
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector<float> val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector<double> val(dimSize);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector< Alembic::Util::int16_t > val(dimSize*2);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector< Alembic::Util::int16_t > val(dimSize*3);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector< Alembic::Util::int32_t > val(dimSize*2);
            if (!isArray)
            {
                int val0, val1;
                val[0] = Alembic::Util::int32_t(val0);
                val[1] = Alembic::Util::int32_t(val1);
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                    int val0, val1;
                    val[2*i] = Alembic::Util::int32_t(val0);
                    val[2*i+1] = Alembic::Util::int32_t(val1);
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector< Alembic::Util::int32_t > val(dimSize*3);
            if (!isArray)
            {
                int val0, val1, val2;
                val[0] = Alembic::Util::int32_t(val0);
                val[1] = Alembic::Util::int32_t(val1);
                val[2] = Alembic::Util::int32_t(val2);
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                    int val0, val1, val2;
                    val[3*i] = Alembic::Util::int32_t(val0);
                    val[3*i+1] = Alembic::Util::int32_t(val1);
                    val[3*i+2] = Alembic::Util::int32_t(val2);
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
            oProp.set(samp);
        }
        break;
        {
            std::vector<float> val(dimSize*2);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector<float> val(dimSize*3);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector<double> val(dimSize*2);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector<double> val(dimSize*3);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        {
            std::vector<double> val(dimSize*4);
            if (!isArray)
            {
            }
            else
            {
                for (unsigned int i = 0; i < numElements; ++i)
                {
                        val[4*i+3]);
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(dimSize));
        }
        break;
        default:
            return false;
        break;
    }
    return true;
}
                          Abc::OScalarProperty & oProp)
{
    size_t dimSize = numElements;
    if (!isArray)
        dimSize = 1;
    switch (iType)
    {
        {
            return MFnNumericDataToSample(numObj.numericType(), iPlug,
                oProp);
        }
        break;
        {
            Abc::OStringProperty strProp( oProp.getPtr(), Abc::kWrapExisting );
            strProp.set(val);
        }
        break;
        {
            double val[16];
            unsigned int i = 0;
            for (unsigned int r = 0; r < 4; r++)
            {
                for (unsigned int c = 0; c < 4; c++, i++)
                {
                    val[i] = mat[r][c];
                }
            }
            oProp.set(&val);
        }
        break;
        default:
            return false;
        break;
    }
    return true;
}
                          Abc::OArrayProperty & oProp)
{
    size_t dimSize = numElements;
    if (!isArray)
        dimSize = 1;
    switch (iType)
    {
        {
            return MFnNumericDataToSample(numObj.numericType(), iPlug,
                oProp);
        }
        break;
        {
            std::vector< std::string > val(1);
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(1));
            oProp.set(samp);
        }
        break;
        {
            unsigned int length = arr.
length();
 
            std::vector< std::string > val(length);
            for (unsigned int i = 0; i < length; i++)
            {
                val[i] = arr[i].asChar();
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(length));
            oProp.set(samp);
        }
        break;
        {
            unsigned int length = arr.
length();
 
            std::vector< double > val(length);
            for (unsigned int i = 0; i < length; i++)
            {
                val[i] = arr[i];
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(length));
            oProp.set(samp);
        }
        break;
        {
            unsigned int length = arr.
length();
 
            std::vector< Alembic::Util::int32_t > val(length);
            for (unsigned int i = 0; i < length; i++)
            {
                val[i] = arr[i];
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(length));
            oProp.set(samp);
        }
        break;
        {
            unsigned int length = arr.
length();
 
            unsigned int extent = oProp.getDataType().getExtent();
            std::vector< double > val(length*extent);
            for (unsigned int i = 0; i < length; i++)
            {
                if (extent > 2)
                if (extent > 3)
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(length));
            oProp.set(samp);
        }
        break;
        {
            unsigned int length = arr.
length();
 
            unsigned int extent = oProp.getDataType().getExtent();
            std::vector< double > val(length*extent);
            for (unsigned int i = 0; i < length; i++)
            {
                if (extent > 2)
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(length));
            oProp.set(samp);
        }
        break;
        {
            std::vector<double> val(16);
            unsigned int i = 0;
            for (unsigned int r = 0; r < 4; r++)
            {
                for (unsigned int c = 0; c < 4; c++, i++)
                {
                    val[i] = mat[r][c];
                }
            }
            AbcA::ArraySample samp(&(val.front()), oProp.getDataType(),
                Alembic::Util::Dimensions(1));
            oProp.set(samp);
        }
        break;
        default:
            return false;
        break;
    }
    return true;
}
bool attributeToScalarPropertyPair(
const MObject& iAttr,
 
                                   Abc::OScalarProperty & oProp)
{
    {
        return MFnTypedDataToSample(typedAttr.
attrType(), iPlug, oProp);
 
    }
    {
        return MFnNumericDataToSample(numAttr.
unitType(), iPlug, oProp);
 
    }
    {
        oProp.set(&dval);
        return true;
    }
    {
        Alembic::Util::int16_t val = iPlug.
asShort();
        oProp.set(&val);
        return true;
    }
    return false;
}
bool attributeToArrayPropertyPair(
const MObject& iAttr,
 
                                  Abc::OArrayProperty & oProp)
{
    {
        return MFnTypedDataToSample(typedAttr.
attrType(), iPlug,
 
            oProp);
    }
    {
        return MFnNumericDataToSample(numAttr.
unitType(), iPlug,
 
            oProp);
    }
    {
        AbcA::ArraySample samp(&val, oProp.getDataType(),
            Alembic::Util::Dimensions(1));
        oProp.set(samp);
        return true;
    }
    {
        Alembic::Util::int16_t val = iPlug.
asShort();
        AbcA::ArraySample samp(&val, oProp.getDataType(),
            Alembic::Util::Dimensions(1));
        oProp.set(samp);
        return true;
    }
    return false;
}
void createUserPropertyFromMFnAttr(
const MObject& iAttr,
 
                                   Abc::OCompoundProperty & iParent,
                                   Alembic::Util::uint32_t iTimeIndex,
                                   AbcGeom::GeometryScope iScope,
                                   std::vector < PlugAndObjScalar > & oScalars,
                                   std::vector < PlugAndObjArray > & oArrays)
{
    {
        if (!stat)
        {
            MString err = 
"Couldn't instantiate MFnNumericAttribute\n\tType: ";
 
            return;
        }
        createUserPropertyFromNumeric(numFn.
unitType(), iAttr, iPlug,
                                      iParent, iTimeIndex, iScope,
                                      oScalars, oArrays);
    }
    {
        if (!stat)
        {
            MString err = 
"Couldn't instantiate MFnTypedAttribute\n\tType: ";
 
            return;
        }
        {
            {
                PlugAndObjScalar p;
                p.plug = iPlug;
                p.obj = iAttr;
                p.prop = Abc::OStringProperty(iParent, plugName, iTimeIndex);
                oScalars.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                p.prop = Abc::OStringArrayProperty(iParent, plugName, iTimeIndex);
                oArrays.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                p.prop = Abc::ODoubleArrayProperty(iParent, plugName, iTimeIndex);
                oArrays.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                p.prop = Abc::OInt32ArrayProperty(iParent, plugName, iTimeIndex);
                oArrays.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                if (iTypeStr  == "point2")
                    p.prop = Abc::OP2dArrayProperty(iParent, plugName, iTimeIndex);
                else
                    p.prop = Abc::OP3dArrayProperty(iParent, plugName, iTimeIndex);
                oArrays.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                if (iTypeStr == "vector2")
                    p.prop = Abc::OV2dArrayProperty(iParent, plugName, iTimeIndex);
                else if (iTypeStr == "normal2")
                    p.prop = Abc::ON2dArrayProperty(iParent, plugName, iTimeIndex);
                else if (iTypeStr == "normal3")
                    p.prop = Abc::ON3dArrayProperty(iParent, plugName, iTimeIndex);
                else
                    p.prop = Abc::OV3dArrayProperty(iParent, plugName, iTimeIndex);
                oArrays.push_back(p);
            }
            break;
            {
                PlugAndObjScalar p;
                p.plug = iPlug;
                p.obj = iAttr;
                p.prop = Abc::OM44dProperty(iParent, plugName, iTimeIndex);
                oScalars.push_back(p);
            }
            break;
            {
                createUserPropertyFromNumeric(numAttr.unitType(), iAttr,
                    iPlug, iParent, iTimeIndex, iScope, oScalars, oArrays);
            }
            break;
            default:
            {
                
                MString msg = 
"WARNING: Couldn't convert ";
 
                msg += " to a property, so skipping.";
            }
            break;
        }
    }
    {
        PlugAndObjScalar p;
        p.plug = iPlug;
        p.obj = iAttr;
        p.prop = Abc::ODoubleProperty(iParent, plugName, iTimeIndex);
        oScalars.push_back(p);
    }
    {
        PlugAndObjScalar p;
        p.plug = iPlug;
        p.obj = iAttr;
        p.prop = Abc::OInt16Property(iParent, plugName, iTimeIndex);
        oScalars.push_back(p);
    }
}
void createGeomPropertyFromMFnAttr(
const MObject& iAttr,
 
                                   Abc::OCompoundProperty & iParent,
                                   Alembic::Util::uint32_t iTimeIndex,
                                   AbcGeom::GeometryScope iScope,
                                   std::vector < PlugAndObjArray > & oArrayVec)
{
    
        return;
    {
        if (!stat)
        {
            MString err = 
"Couldn't instantiate MFnNumericAttribute\n\tType: ";
 
            return;
        }
        createGeomPropertyFromNumeric(numFn.
unitType(), iAttr, iPlug, iParent,
            iTimeIndex, iScope, oArrayVec);
    }
    {
        if (!stat)
        {
            MString err = 
"Couldn't instantiate MFnTypedAttribute\n\tType: ";
 
            return;
        }
        {
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                AbcGeom::OStringGeomParam gp(iParent, plugName, false, iScope,
                    1, iTimeIndex);
                p.prop = gp.getValueProperty();
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                AbcGeom::OStringGeomParam gp(iParent, plugName, false, iScope,
                    1, iTimeIndex);
                p.prop = gp.getValueProperty();
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                AbcGeom::ODoubleGeomParam gp(iParent, plugName, false, iScope,
                    1, iTimeIndex);
                p.prop = gp.getValueProperty();
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                AbcGeom::OInt32GeomParam gp(iParent, plugName, false, iScope,
                    1, iTimeIndex);
                p.prop = gp.getValueProperty();
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                if (iTypeStr  == "point2")
                {
                    AbcGeom::OP2dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                else
                {
                    AbcGeom::OP3dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                if (iTypeStr == "vector2")
                {
                    AbcGeom::OV2dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                else if (iTypeStr == "normal2")
                {
                    AbcGeom::ON2dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                else if (iTypeStr == "normal3")
                {
                    AbcGeom::ON3dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                else
                {
                    AbcGeom::OV3dGeomParam gp(iParent, plugName, false, iScope,
                        1, iTimeIndex);
                    p.prop = gp.getValueProperty();
                }
                oArrayVec.push_back(p);
            }
            break;
            {
                PlugAndObjArray p;
                p.plug = iPlug;
                p.obj = iAttr;
                AbcGeom::OM44dGeomParam gp(iParent, plugName, false, iScope, 1,
                    iTimeIndex);
                p.prop = gp.getValueProperty();
                oArrayVec.push_back(p);
            }
            break;
            {
                createGeomPropertyFromNumeric(numAttr.unitType(), iAttr,
                    iPlug, iParent, iTimeIndex, iScope, oArrayVec);
            }
            break;
            default:
            {
                
                MString msg = 
"WARNING: Couldn't convert ";
 
                msg += " to a property, so skipping.";
            }
            break;
        }
    }
    {
        PlugAndObjArray p;
        p.plug = iPlug;
        p.obj = iAttr;
        AbcGeom::ODoubleGeomParam gp(iParent, plugName, false, iScope, 1,
            iTimeIndex);
        p.prop = gp.getValueProperty();
        oArrayVec.push_back(p);
    }
    {
        PlugAndObjArray p;
        p.plug = iPlug;
        p.obj = iAttr;
        AbcGeom::OInt16GeomParam gp(iParent, plugName, false, iScope, 1,
            iTimeIndex);
        p.prop = gp.getValueProperty();
        oArrayVec.push_back(p);
    }
}
}
AttributesWriter::AttributesWriter(
    Alembic::Abc::OCompoundProperty & iArbGeom,
    Alembic::Abc::OCompoundProperty & iUserProps,
    Alembic::Abc::OObject & iParentObj,
    Alembic::Util::uint32_t iTimeIndex,
    const JobArgs & iArgs)
{
    PlugAndObjScalar visPlug;
    unsigned int i;
    std::vector< PlugAndObjArray > staticPlugObjArrayVec;
    std::vector< PlugAndObjScalar > staticPlugObjScalarVec;
    for (i = 0; i < attrCount; i++)
    {
        
        if (!mfnAttr.isReadable() || plug.
isNull())
 
            continue;
        std::string propStr = propName.
asChar();
        
        if (propStr == "visibility")
        {
            if (iArgs.writeVisibility)
            {
                visPlug.plug = plug;
                visPlug.obj = attr;
            }
            continue;
        }
        bool userAttr = false;
        if (!matchFilterOrAttribs(plug, iArgs, userAttr))
            continue;
        if (userAttr && !iUserProps.valid())
            continue;
        if (!userAttr && !iArbGeom.valid())
            continue;
        int sampType = util::getSampledType(plug);
        AbcGeom::GeometryScope scope = AbcGeom::kUnknownScope;
        {
            scope = strToScope(scopePlug.
asString());
        }
        {
        }
        if (userAttr)
        {
            switch (sampType)
            {
                
                case 0:
                {
                    
                    
                    
                    
                    
                    createUserPropertyFromMFnAttr(attr, plug, iUserProps, 0,
                        scope, typeStr, staticPlugObjScalarVec,
                        staticPlugObjArrayVec);
                }
                break;
                
                case 1:
                
                case 2:
                {
                    
                    
                    
                    
                    
                    createUserPropertyFromMFnAttr(attr, plug, iUserProps,
                        iTimeIndex, scope, typeStr, mPlugObjScalarVec,
                        mPlugObjArrayVec);
                }
                break;
            }
        }
        else
        {
            switch (sampType)
            {
                
                case 0:
                {
                    
                    
                    
                    
                    createGeomPropertyFromMFnAttr(attr, plug, iArbGeom, 0,
                        scope, typeStr, staticPlugObjArrayVec);
                }
                break;
                
                case 1:
                
                case 2:
                {
                    
                    
                    
                    
                    
                    
                    createGeomPropertyFromMFnAttr(attr, plug, iArbGeom,
                        iTimeIndex, scope, typeStr, mPlugObjArrayVec);
                }
                break;
            }
        }
    }
    
    std::vector< PlugAndObjScalar >::iterator k =
        staticPlugObjScalarVec.begin();
    std::vector< PlugAndObjScalar >::iterator kend =
        staticPlugObjScalarVec.end();
    for (; k != kend; k++)
    {
        MString propName = k->plug.partialName(0, 0, 0, 0, 0, 1);
 
        
        
        bool filledProp = attributeToScalarPropertyPair(k->obj, k->plug,
            k->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get static scalar property ";
 
            msg += k->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    
    std::vector< PlugAndObjArray >::iterator j =
        staticPlugObjArrayVec.begin();
    std::vector< PlugAndObjArray >::iterator jend =
        staticPlugObjArrayVec.end();
    for (; j != jend; j++)
    {
        MString propName = j->plug.partialName(0, 0, 0, 0, 0, 1);
 
        bool filledProp = attributeToArrayPropertyPair(j->obj, j->plug,
            j->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get static array property ";
 
            msg += j->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    
    k = mPlugObjScalarVec.begin();
    kend = mPlugObjScalarVec.end();
    for (; k != kend; ++k)
    {
        MString propName = k->plug.partialName(0, 0, 0, 0, 0, 1);
 
        bool filledProp = attributeToScalarPropertyPair(k->obj, k->plug,
            k->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get scalar property ";
 
            msg += k->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    
    j = mPlugObjArrayVec.begin();
    jend = mPlugObjArrayVec.end();
    for (; j != jend; j++)
    {
        MString propName = j->plug.partialName(0, 0, 0, 0, 0, 1);
 
        bool filledProp = attributeToArrayPropertyPair(j->obj, j->plug,j->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get array property ";
 
            msg += j->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    
    
    if (!visPlug.plug.isNull())
    {
        int retVis = util::getVisibilityType(visPlug.plug);
        
        Abc::OCompoundProperty parent = iParentObj.getProperties();
        switch (retVis)
        {
            
            case 1:
            {
                Alembic::Util::int8_t visVal =
                    Alembic::AbcGeom::kVisibilityHidden;
                Abc::OCharProperty bp =
                    Alembic::AbcGeom::CreateVisibilityProperty(
                        iParentObj, 0);
                bp.set(visVal);
            }
            break;
            
            case 2:
            {
                Alembic::Util::int8_t visVal =
                    Alembic::AbcGeom::kVisibilityHidden;
                Abc::OCharProperty bp = 
                    Alembic::AbcGeom::CreateVisibilityProperty(
                        iParentObj, iTimeIndex);
                bp.set(visVal);
                visPlug.prop = bp;
                mAnimVisibility = visPlug;
            }
            break;
            
            case 3:
            {
                
                if (iTimeIndex == 0)
                {
                    break;
                }
                mAnimVisibility = visPlug;
                Alembic::Util::int8_t visVal =
                    Alembic::AbcGeom::kVisibilityDeferred;
                Abc::OCharProperty bp = 
                    Alembic::AbcGeom::CreateVisibilityProperty(
                        iParentObj, iTimeIndex);
                bp.set(visVal);
                visPlug.prop = bp;
                mAnimVisibility = visPlug;
            }
            break;
            
            default:
            break;
        }
    }
}
bool AttributesWriter::matchFilterOrAttribs(
const MPlug & iPlug,
 
                                            const JobArgs & iArgs,
                                            bool& userAttrOut)
{
    std::string name = propName.
asChar();
    if (name.find("[") != std::string::npos)
    {
        return false;
    }
    
    std::vector<std::string>::const_iterator f;
    std::vector<std::string>::const_iterator fEnd =
        iArgs.prefixFilters.end();
    for (f = iArgs.prefixFilters.begin(); f != fEnd; ++f)
    {
        
        
        if (f->length() > 0 &&
            name.compare(0, f->length(), *f) == 0 &&
            !endsWithArbAttr(name) &&
        {
            userAttrOut = false;
            return true;
        }
    }
    
    
    std::vector<std::string>::const_iterator it;
    std::vector<std::string>::const_iterator itEnd =
        iArgs.userPrefixFilters.end();
    for (it = iArgs.userPrefixFilters.begin(); it != itEnd; ++it)
    {
        
        
        if (it->length() > 0 &&
            name.compare(0, it->length(), *it) == 0 &&
            !endsWithArbAttr(name) &&
        {
            userAttrOut = true;
            return true;
        }
    }
    
    if (iArgs.attribs.find(name) != iArgs.attribs.end())
    {
        userAttrOut = false;
        return true;
    }
    if (iArgs.userAttribs.find(name) != iArgs.userAttribs.end())
    {
        userAttrOut = true;
        return true;
    }
    return false;
}
                                  const JobArgs & iArgs)
{
    unsigned int i;
    std::vector< PlugAndObjArray > staticPlugObjArrayVec;
    bool userAttr;
    for (i = 0; i < attrCount; i++)
    {
        
        if (!mfnAttr.isReadable() || plug.
isNull())
 
        {
            continue;
        }
        if (matchFilterOrAttribs(plug, iArgs, userAttr))
        {
            return true;
        }
    }
    return false;
}
AttributesWriter::~AttributesWriter()
{
}
bool AttributesWriter::isAnimated()
{
    return !mPlugObjArrayVec.empty() || !mAnimVisibility.plug.
isNull() ||
 
           !mPlugObjScalarVec.empty();
}
void AttributesWriter::write()
{
    std::vector< PlugAndObjArray >::iterator j =
        mPlugObjArrayVec.begin();
    std::vector< PlugAndObjArray >::iterator jend =
        mPlugObjArrayVec.end();
    for (; j != jend; j++)
    {
        MString propName = j->plug.partialName(0, 0, 0, 0, 0, 1);
 
        bool filledProp = attributeToArrayPropertyPair(j->obj, j->plug, j->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get sampled array property ";
 
            msg += j->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    std::vector< PlugAndObjScalar >::iterator k =
        mPlugObjScalarVec.begin();
    std::vector< PlugAndObjScalar >::iterator kend =
        mPlugObjScalarVec.end();
    for (; k != kend; ++k)
    {
        MString propName = k->plug.partialName(0, 0, 0, 0, 0, 1);
 
        bool filledProp = attributeToScalarPropertyPair(k->obj, k->plug,
            k->prop);
        if (!filledProp)
        {
            MString msg = 
"WARNING: Couldn't get sampled scalar property ";
 
            msg += k->plug.partialName(1, 0, 0, 0, 1, 1);
            msg += ", so skipping.";
            continue;
        }
    }
    if (!mAnimVisibility.plug.isNull())
    {
        Alembic::Util::int8_t visVal = -1;
        if (!mAnimVisibility.plug.asBool())
        {
            visVal = 0;
        }
        mAnimVisibility.prop.set(&visVal);
    }
}