void readSubD(double iFrame, MFnMesh & ioMesh, MObject & iParent,
    Alembic::AbcGeom::ISubD & iNode, bool iInitialized)
{
    Alembic::AbcGeom::ISubDSchema schema = iNode.getSchema();
    Alembic::AbcGeom::MeshTopologyVariance ttype = schema.getTopologyVariance();

    int64_t index, ceilIndex;
    double alpha = getWeightAndIndex(iFrame,
        schema.getTimeSampling(), schema.getNumSamples(), index, ceilIndex);

    MFloatPointArray pointArray;
    Alembic::Abc::V3fArraySamplePtr ceilPoints;

    // we can just read the points
    if (ttype != Alembic::AbcGeom::kHeterogenousTopology && iInitialized)
    {

        Alembic::Abc::V3fArraySamplePtr points = schema.getPositions().getValue(
            Alembic::Abc::ISampleSelector(index) );

        if (alpha != 0.0)
        {
            ceilPoints = schema.getPositions().getValue(
                Alembic::Abc::ISampleSelector(ceilIndex) );
        }

        fillPoints(pointArray, points, ceilPoints, alpha);
        ioMesh.setPoints(pointArray, MSpace::kObject);

        if (schema.getUVs().getNumSamples() > 1)
        {
            setUVs(iFrame, ioMesh, schema.getUVs());
        }

        return;
    }

    // we need to read the topology
    Alembic::AbcGeom::ISubDSchema::Sample samp;
    schema.get(samp, Alembic::Abc::ISampleSelector(index));

    if (alpha != 0.0 && ttype != Alembic::AbcGeom::kHeterogenousTopology)
    {
        ceilPoints = schema.getPositions().getValue(
            Alembic::Abc::ISampleSelector(ceilIndex) );
    }

    fillPoints(pointArray, samp.getPositions(), ceilPoints, alpha);

    fillTopology(ioMesh, iParent, pointArray, samp.getFaceIndices(),
        samp.getFaceCounts());

    setUVs(iFrame, ioMesh, schema.getUVs());
}