예제 #1
0
void readEmptyCompoundProperties(const std::string &archiveName)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const int numChildren = archiveTop.getNumChildren();
    ABCA_ASSERT( numChildren == 2, "Wrong number of children (expected 2)");
    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;

    // Iterate through them, print out their names
    for (int ii=0; ii<numChildren; ii++)
    {
        IObject child( archiveTop, archiveTop.getChildHeader(ii).getName() );
        std::cout << "  " << child.getName();

        std::cout << " has " << child.getNumChildren() << " children"
                  << std::endl;

        // Properties
        ICompoundProperty props = child.getProperties();
        int numProperties = props.getNumProperties();

        std::cout << "  ..and " << numProperties << " properties"
                  << std::endl;

        std::vector<std::string> propNames;
        for (int pp=0; pp<numProperties; pp++)
            propNames.push_back( props.getPropertyHeader(pp).getName() );

        for (int jj=0; jj<numProperties; jj++)
        {
            std::cout << "    ..named " << propNames[jj] << std::endl;

            std::cout << "    ..with type: ";
            PropertyType pType = props.getPropertyHeader(jj).getPropertyType();
            if (pType == kCompoundProperty)
            {
                std::cout << "compound" << std::endl;
            }
            else if (pType == kScalarProperty)
            {
                std::cout << "scalar" << std::endl;
            }
            else if (pType == kArrayProperty)
            {
                std::cout << "array" << std::endl;
            }
        }
    }

    // Done - the archive closes itself

}
예제 #2
0
void readDeepHierarchy(const std::string &archiveName)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const unsigned int numChildren = archiveTop.getNumChildren();
    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;

    ABCA_ASSERT( numChildren == 2,
                 "Expected 2 children, found " << numChildren );

    // Iterate through them, print out their names
    for (unsigned int ii=0; ii<numChildren; ii++)
    {
        IObject child( archiveTop, archiveTop.getChildHeader(ii).getName() );
        std::cout << "  " << child.getName();

        recursivelyReadChildren( child );
    }


    // do it again to make sure we clean up after ourselves properly
    IArchive archive2 = factory.getArchive(archiveName, coreType);
    IObject archiveTop2 = archive2.getTop();


    // Done - the archive closes itself
}
//-*****************************************************************************
void simpleTestIn( const std::string &iArchiveName )
{
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(iArchiveName, coreType);

    IObject archiveTop = archive.getTop();

    TESTING_ASSERT( archiveTop.getNumChildren() == ( size_t )NUM_TOP_CHILDREN );

    for ( int i = 0 ; i < NUM_TOP_CHILDREN ; i++ )
    {
        std::ostringstream strm;
        strm << i;
        std::string cname = strm.str();
        IObject obj( archiveTop, cname );
        readDeepHierarchy( obj, 0, obj  );
    }

    TESTING_ASSERT( PATHS.size() == ( size_t ) NUM_TOP_CHILDREN );
}
예제 #4
0
void readFlatHierarchy(const std::string &archiveName)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const int numChildren = archiveTop.getNumChildren();
    ABCA_ASSERT( numChildren == 10,
                 "Expected 10 children, found " << numChildren );

    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;

    // Iterate through them, print out their names
    for (int ii=0; ii<numChildren; ii++)
    {
        IObject child( archiveTop,
                       archiveTop.getChildHeader(ii).getName() );
        std::cout << "  " << child.getName();

        const unsigned int children = child.getNumChildren();
        std::cout << " has " << children << " children"
                  << std::endl;

        ABCA_ASSERT( children == 0,
                     "Expected no children, found " << children );

    }

    // Done - the archive closes itself
}
예제 #5
0
void readSimpleProperties(const std::string &archiveName)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const int numChildren = archiveTop.getNumChildren();
    TESTING_ASSERT( numChildren == 4 );
    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;

    // Iterate through them, print out their names
    for (int ii=0; ii<numChildren; ii++)
    {
        IObject child( archiveTop, archiveTop.getChildHeader( ii ).getName() );
        std::cout << "  " << child.getName();

        std::cout << " has " << child.getNumChildren() << " children"
                  << std::endl;

        // Properties
        ICompoundProperty props = child.getProperties();
        int numProperties = props.getNumProperties();

        std::cout << "  ..and " << numProperties << " simple properties"
                  << std::endl;

        std::vector<std::string> propNames;
        for (int pp=0; pp<numProperties; pp++)
            propNames.push_back( props.getPropertyHeader(pp).getName() );

        for (int jj=0; jj<numProperties; jj++)
        {
            std::cout << "    ..named " << propNames[jj] << std::endl;

            std::cout << "    ..with type: ";
            PropertyType pType = props.getPropertyHeader(jj).getPropertyType();
            if (pType == kCompoundProperty)
            {
                std::cout << "compound" << std::endl;
            }
            else if (pType == kScalarProperty)
            {
                std::cout << "scalar" << std::endl;
            }
            else if (pType == kArrayProperty)
            {
                std::cout << "array" << std::endl;
            }

            DataType dType = props.getPropertyHeader(jj).getDataType();
            std::cout << "    ..with POD-type: ";

            switch (dType.getPod())
            {
                case  kBooleanPOD:
                    std::cout << "boolean" << std::endl;
                    break;

                // Char/UChar
                case kUint8POD:
                    std::cout << "unsigned char" << std::endl;
                    break;
                case kInt8POD:
                    std::cout << "char" << std::endl;
                    break;

                // Short/UShort
                case kUint16POD:
                    std::cout << "short unsigned int" << std::endl;
                    break;
                case kInt16POD:
                    std::cout << "short int" << std::endl;
                    break;

                // Int/UInt
                case kUint32POD:
                    std::cout << "unsigned int" << std::endl;
                    break;
                case kInt32POD:
                    std::cout << "int" << std::endl;
                    break;

                // Long/ULong
                case kUint64POD:
                    std::cout << "unsigned long int" << std::endl;
                    break;
                case kInt64POD:
                    std::cout << "long int" << std::endl;
                    break;

                // Half/Float/Double
                case kFloat16POD:
                    std::cout << "half" << std::endl;
                    break;
                case kFloat32POD:
                    std::cout << "float" << std::endl;
                    break;
                case kFloat64POD:
                    std::cout << "double" << std::endl;
                    break;

                case kStringPOD:
                    std::cout << "string" << std::endl;
                    break;

                case kUnknownPOD:
                default:
                    std::cout << " Unknown! (this is bad)" << std::endl;
            };

            TimeSamplingPtr ts =
                GetCompoundPropertyReaderPtr(props)->
                getScalarProperty( propNames[jj] )->getTimeSampling();

            int numSamples = ts->getNumStoredTimes();


            std::cout << "    ..and "
                      << ts->getTimeSamplingType() << std::endl
                      << "    ..and " << numSamples << " samples at times: ";

            if (numSamples > 0)
            {
                std::cout << " ( ";
                for (int ss=0; ss<numSamples; ss++)
                    std::cout << ts->getSampleTime(ss) << " ";
                std::cout << ")";
            }
            std::cout << std::endl;

            std::cout << "    ..and values: ";
            if (numSamples > 0)
            {
                for (int ss=0; ss<numSamples; ss++)
                {
                    ISampleSelector iss( (index_t) ss);
                    switch (dType.getPod())
                    {
                        // Boolean
                        case  kBooleanPOD:
                        {
                            IBoolProperty prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        // Char/UChar
                        case kUint8POD:
                        {
                            IUcharProperty prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }
                        case kInt8POD:
                        {
                            ICharProperty prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        // Short/UShort
                        case kUint16POD:
                        {
                            IUInt16Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }
                        case kInt16POD:
                        {
                            IInt16Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        // Int/UInt
                        case kUint32POD:
                        {
                            IUInt32Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }
                        case kInt32POD:
                        {
                            IInt32Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        // Long/ULong
                        case kUint64POD:
                        {
                            IUInt64Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }
                        case kInt64POD:
                        {
                            IInt64Property prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        // Half/Float/Double
                        case kFloat16POD:
                            // iostream doesn't understand float_16's
                            //printSampleValue( IHalfProperty( props,  propNames[jj] ),
                            //                  iss );
                            break;
                        case kFloat32POD:
                        {
                            IFloatProperty prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }
                        case kFloat64POD:
                        {
                            IDoubleProperty prop( props,  propNames[jj] );
                            printSampleValue( prop, iss );
                            break;
                        }

                        case kUnknownPOD:
                        default:
                            std::cout << " Unknown! (this is bad)" << std::endl;
                    };

                }
            }
            std::cout << std::endl;



            std::cout << std::endl; // done parsing property
        }
    }

    // Done - the archive closes itself
}
예제 #6
0
void errorHandlerTest(bool useOgawa)
{

    {
        OArchive archive;
        if (useOgawa)
        {
            archive = OArchive( Alembic::AbcCoreOgawa::WriteArchive(),
                "throwTest.abc", ErrorHandler::kThrowPolicy );
        }
        else
        {
            archive = OArchive( Alembic::AbcCoreHDF5::WriteArchive(),
                "throwTest.abc", ErrorHandler::kThrowPolicy );
        }

        OObject archiveTop = archive.getTop();
        ABCA_ASSERT( archiveTop.getErrorHandler().getPolicy() ==
            ErrorHandler::kThrowPolicy, "Error: Not kThrowPolicy" );
        OObject childQuiet(archiveTop, "childQuiet",
            ErrorHandler::kQuietNoopPolicy );
        OObject childNoisy(archiveTop, "childNoisy",
            ErrorHandler::kNoisyNoopPolicy );

        OObject grandchildQuiet(childQuiet, "grandchildQuiet" );
        OObject grandchildNoisy(childNoisy, "grandchildNoisy" );

        ABCA_ASSERT( childQuiet.getErrorHandler().getPolicy() ==
            ErrorHandler::kQuietNoopPolicy, "Error: Not kQuietNoopPolicy" );
        ABCA_ASSERT( childNoisy.getErrorHandler().getPolicy() ==
            ErrorHandler::kNoisyNoopPolicy, "Error: Not kNoisyNoopPolicy" );

        ABCA_ASSERT( grandchildQuiet.getErrorHandler().getPolicy() ==
            ErrorHandler::kQuietNoopPolicy, "Error: Not kQuietNoopPolicy" );
        ABCA_ASSERT( grandchildNoisy.getErrorHandler().getPolicy() ==
            ErrorHandler::kNoisyNoopPolicy, "Error: Not kNoisyNoopPolicy" );
    }

    {
        AbcF::IFactory factory;
        factory.setPolicy(  ErrorHandler::kThrowPolicy );
        AbcF::IFactory::CoreType coreType;
        IArchive archive = factory.getArchive("throwTest.abc", coreType);
        IObject archiveTop = archive.getTop();

        ABCA_ASSERT( archiveTop.getErrorHandler().getPolicy() ==
            ErrorHandler::kThrowPolicy, "Error: Not kThrowPolicy" );
        IObject childQuiet(archiveTop, "childQuiet",
            ErrorHandler::kQuietNoopPolicy );
        IObject childNoisy(archiveTop, "childNoisy",
            ErrorHandler::kNoisyNoopPolicy );
        IObject grandchildQuiet(childQuiet, "grandchildQuiet" );
        IObject grandchildNoisy(childNoisy, "grandchildNoisy" );
        ABCA_ASSERT( childQuiet.getErrorHandler().getPolicy() ==
            ErrorHandler::kQuietNoopPolicy, "Error: Not kQuietNoopPolicy" );
        ABCA_ASSERT( childNoisy.getErrorHandler().getPolicy() ==
            ErrorHandler::kNoisyNoopPolicy, "Error: Not kNoisyNoopPolicy" );

        ABCA_ASSERT( grandchildQuiet.getErrorHandler().getPolicy() ==
            ErrorHandler::kQuietNoopPolicy, "Error: Not kQuietNoopPolicy" );
        ABCA_ASSERT( grandchildNoisy.getErrorHandler().getPolicy() ==
            ErrorHandler::kNoisyNoopPolicy, "Error: Not kNoisyNoopPolicy" );
    }
}
예제 #7
0
//-*****************************************************************************
//-*****************************************************************************
// DO IT.
//-*****************************************************************************
//-*****************************************************************************
int main( int argc, char *argv[] )
{
    if (argc < 4)
    {
        std::cerr << "USAGE: " << argv[0] << " outFile.abc inFile1.abc"
            << " inFile2.abc (inFile3.abc ...)" << std::endl;
        return -1;
    }

    {
        size_t numInputs = argc - 2;
        std::vector< chrono_t > minVec;

        minVec.reserve(numInputs);

        std::vector< IArchive > iArchives;
        iArchives.reserve(numInputs);

        std::map< chrono_t, size_t > minIndexMap;
        size_t rootChildren = 0;

        Alembic::AbcCoreFactory::IFactory factory;
        factory.setPolicy(ErrorHandler::kThrowPolicy);
        Alembic::AbcCoreFactory::IFactory::CoreType coreType;

        for (int i = 2; i < argc; ++i)
        {

            IArchive archive = factory.getArchive(argv[i], coreType);
            if (!archive.valid() || archive.getTop().getNumChildren() < 1)
            {
                std::cerr << "ERROR: " << argv[i] <<
                    " not a valid Alembic file" << std::endl;
                return 1;
            }

            IObject iRoot = archive.getTop();
            size_t numChildren = iRoot.getNumChildren();

            if (i == 2)
            {
                rootChildren = numChildren;
            }
            else if (rootChildren != numChildren)
            {
                std::cerr << "ERROR: " << argv[i] <<
                    " doesn't have the same number of children as: " <<
                    argv[i-1] << std::endl;
            }

            // reorder the input files according to their mins
            chrono_t min = DBL_MAX;
            Alembic::Util::uint32_t numSamplings = archive.getNumTimeSamplings();
            if (numSamplings > 1)
            {
                // timesampling index 0 is special, so it will be skipped
                //
                // make sure all the other timesampling objects start at
                // the same time or throw here
                //
                min = archive.getTimeSampling(1)->getSampleTime(0);

                for (Alembic::Util::uint32_t s = 2; s < numSamplings; ++s)
                {
                    chrono_t thisMin =
                        archive.getTimeSampling(s)->getSampleTime(0);

                    if (fabs(thisMin - min) > 1e-5)
                    {
                        std::cerr << "ERROR: " << argv[i]
                            << " has non-default TimeSampling objects"
                            << " that don't start at the same time."
                            << std::endl;
                        return 1;
                    }
                }

                minVec.push_back(min);
                if (minIndexMap.count(min) == 0)
                {
                    minIndexMap.insert(std::make_pair(min, i-2));
                }
                else if (argv[2] != argv[i])
                {
                    std::cerr << "ERROR: overlapping frame range between "
                        << argv[2] << " and " << argv[i] << std::endl;
                    return 1;
                }
            }
            else
            {
                std::cerr << "ERROR: " << archive.getName() <<
                    " only has default (static) TimeSampling." << std::endl;
                return 1;
            }

            iArchives.push_back(archive);
        }

        // now reorder the input nodes so they are in increasing order of their
        // min values in the frame range
        std::sort(minVec.begin(), minVec.end());
        std::vector< IArchive > iOrderedArchives;
        iOrderedArchives.reserve(numInputs);

        for (size_t f = 0; f < numInputs; ++f)
        {
            size_t index = minIndexMap.find(minVec[f])->second;
            iOrderedArchives.push_back(iArchives[index]);
        }

        std::string appWriter = "AbcStitcher";
        std::string fileName = argv[1];
        std::string userStr;

        // Create an archive with the default writer
        OArchive oArchive;
        if (coreType == Alembic::AbcCoreFactory::IFactory::kHDF5)
        {
            oArchive = CreateArchiveWithInfo(
                Alembic::AbcCoreHDF5::WriteArchive(),
                fileName, appWriter, userStr, ErrorHandler::kThrowPolicy);
        }
        else if (coreType == Alembic::AbcCoreFactory::IFactory::kOgawa)
        {
            oArchive = CreateArchiveWithInfo(
                Alembic::AbcCoreOgawa::WriteArchive(),
                fileName, appWriter, userStr, ErrorHandler::kThrowPolicy);
        }

        OObject oRoot = oArchive.getTop();
        if (!oRoot.valid())
            return -1;

        std::vector<IObject> iRoots;
        iRoots.resize(numInputs);
        for (size_t f = 0; f < rootChildren; ++f)
        {
            for (size_t g = 0; g < numInputs; ++g)
            {
                iRoots[g] = iOrderedArchives[g].getTop().getChild(f);
            }

            visitObjects(iRoots, oRoot);
        }

        // collect the top level compound property
        ICompoundPropertyVec iCompoundProps;
        iCompoundProps.reserve(numInputs);
        for (size_t f = 0; f < numInputs; ++f)
        {
            iCompoundProps.push_back(iRoots[f].getParent().getProperties());
        }

        OCompoundProperty oCompoundProperty = oRoot.getProperties();
        stitchCompoundProp(iCompoundProps, oCompoundProperty);

    }

    return 0;
}
예제 #8
0
파일: AbcLs.cpp 프로젝트: alembic/alembic
//-*****************************************************************************
int main( int argc, char *argv[] )
{
    //float opt_fps = 24.0;
    bool opt_all = false; // show all option
    bool opt_long = false; // long listing option
    bool opt_meta = false; // metadata option
    bool opt_recursive = false; // recursive option
    bool opt_size = false; // array sample size option
    bool opt_time = false; // time info option
    bool opt_values = false; // show all 0th values
    int index = -1; // sample number, at tail of path
    std::string desc( "abcls [OPTION] FILE[/NAME] \n"
    "  -a          include property listings\n"
    "  -f          show time sampling as 24 fps\n"
    "  -h, --help  show this help message\n"
    "  -l          long listing format\n"
    "  -m          show archive metadata\n"
    "  -r          list entries recursively\n"
    "  -s          show the size of a data property sample\n"
    "  -t          show time sampling information\n"
    "  -v          show 0th value for all properties\n"
    );

    /* sigaction if available */
#if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L)
    // seg fault handler
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_handler = segfault_sigaction;
    act.sa_flags = SA_SIGINFO;
    sigaction(SIGSEGV, &act, NULL);
    /* signal if available */
#elif defined(_POSIX_VERSION) || defined(_MSC_VER)
    signal(SIGSEGV, segfault_sigaction);
#else
#error No signal interface available
#endif //_POSIX_VERSION

    // check for min args
    if ( argc < 2 ) {
        std::cout << desc << std::endl;
        return 0;
    };

    // parse args
    std::vector<std::string> arguments(argv, argv + argc);
    std::vector<std::string> options;
    std::vector<std::string> files;

    // separate file args from option args
    for ( std::size_t i = 1; i < arguments.size(); i++ ) {
        if ( arguments[ i ].substr( 0, 1 ) == "-" )
            options.push_back( arguments[ i ] );
        else
            files.push_back( arguments[ i ] );
    }

    // help
    if ( argc < 2 ||
         optionExists( options, "h" ) ||
         optionExists( options, "help" )
       ) {
        std::cout << desc << std::endl;
        return 0;
    };

    // set some flags
    double fps = 1.0;
    opt_all = optionExists( options, "a" );
    opt_long = optionExists( options, "l" );
    opt_meta = optionExists( options, "m" );
    opt_recursive = optionExists( options, "r" );
    opt_size = optionExists( options, "s" );
    opt_time = optionExists( options, "t" );
    opt_values = optionExists( options, "v" );
    if ( optionExists( options, "f" ) ) {
        fps = 24.0;
        opt_time = true;
    }

    // open each file
    for ( std::size_t i = 0; i < files.size(); i++ ) {
        if ( files.size() > 1 )
            std::cout << BOLD << files[i] << ':' << RESETCOLOR << std::endl;

        std::stringstream ss( files[i] );
        std::stringstream fp;
        std::string segment;
        std::vector<std::string> seglist;

        /*
         * separate file and object paths, e.g.
         *
         *   ../dir1/foo.abc/bar/baz/index
         *   \_____________/\______/\____/
         *        file         obj   sample
         */
        int j = 0;
        while ( std::getline( ss, segment, '/' ) ) {
            if ( !isFile ( fp.str() ) ) {
                if ( j != 0 )
                    fp << "/";
                fp << segment;
            } else {
                seglist.push_back( segment );
            }
            ++j;
        }

        bool lastIsIndex = false;
        if (!seglist.empty() && is_digit( seglist.back() ) ) {
            index = atoi( seglist.back().c_str() );
            lastIsIndex = true;
        }

        // open the iarchive
        Abc::IArchive archive;
        AbcF::IFactory factory;
        factory.setPolicy(Abc::ErrorHandler::kQuietNoopPolicy);
        AbcF::IFactory::CoreType coreType;
        archive = factory.getArchive(std::string( fp.str() ), coreType);

        // display file metadata
        if ( opt_meta && seglist.size() == 0 ) {
            std::cout  << "Using "
                       << Alembic::AbcCoreAbstract::GetLibraryVersion()
                       << std::endl;;

            std::string appName;
            std::string libraryVersionString;
            Alembic::Util::uint32_t libraryVersion;
            std::string whenWritten;
            std::string userDescription;
            std::string coreName;
            GetArchiveInfo (archive,
                            appName,
                            libraryVersionString,
                            libraryVersion,
                            whenWritten,
                            userDescription);

            if ( coreType == AbcF::IFactory::kOgawa ) {
                coreName = "Ogawa";
            } else if ( coreType == AbcF::IFactory::kHDF5 ) {
                coreName = "HDF5";
            } else {
                coreName = "Unknown";
            };

            if ( appName != "" ) {
                std::cout << "  file written by: " << appName << std::endl;
                std::cout << "  using Alembic : " << libraryVersionString << std::endl;
                std::cout << "  written on : " << whenWritten << std::endl;
                std::cout << "  user description : " << userDescription << std::endl;
            } else {
                std::cout << "  (file doesn't have any ArchiveInfo)"
                          << std::endl;
            }
            std::cout << "  core type : " << coreName << std::endl;
        };

        if ( opt_time && seglist.size() == 0 ) {
            uint32_t numTimes = archive.getNumTimeSamplings();
            std::cout << std::endl << "Time Samplings: " << std::endl;
            for ( uint32_t k = 0; k < numTimes; ++k ) {
                AbcA::TimeSamplingPtr ts = archive.getTimeSampling( k );
                index_t maxSample =
                    archive.getMaxNumSamplesForTimeSamplingIndex( k );
                std::cout << k << " ";
                printTimeSampling( ts, maxSample, fps );
            }
            std::cout << std::endl;

        }

        // walk object hierarchy and find valid objects
        AbcG::IObject test = archive.getTop();
        AbcG::IObject iObj = test;
        while ( test.valid() && seglist.size() > 0 ) {
            test = test.getChild( seglist.front() );
            if ( test.valid() ) {
                iObj = test;
                seglist.erase( seglist.begin() );
            }
        }

        // walk property hierarchy for most recent object
        Abc::ICompoundProperty props = iObj.getProperties();
        const Abc::PropertyHeader* header;
        bool found = false;
        bool shouldPrintValue = false;
        for ( std::size_t i = 0; i < seglist.size(); ++i ) {
            header = props.getPropertyHeader( seglist[i] );
            if ( header && header->isCompound() ) {
                Abc::ICompoundProperty ptest( props, header->getName() );
                if ( ptest.valid() ) {
                    props = ptest;
                    found = true;
                }
            } else if ( header && header->isSimple() ) {
                found = true;

                // if the last value happens to be an index, and we are a
                // property  then dont bother checking the last item in seglist
                if (lastIsIndex && i == seglist.size() - 2)
                {
                    shouldPrintValue = true;
                    break;
                }
            } else {
                std::cout << seglist[i]
                          << ": Invalid object or property"
                          << std::endl;
                return 1;
            }
        }

        // do stuff
        if ( shouldPrintValue ) {
            printValue( props, *header, index, opt_size, opt_time, fps );
        } else {
            if ( found && header->isCompound() )
                visit( props, opt_all, opt_long, opt_meta, opt_recursive, true, opt_values );
            else if ( found && header->isSimple() )
                printChild( props, *header, opt_all, opt_long, opt_values );
            else
                visit( iObj, opt_all, opt_long, opt_meta, opt_recursive, true, opt_values );
            std::cout << RESETCOLOR;
            if ( !opt_long )
                std::cout << std::endl;
        }
    }
    return 0;
}
예제 #9
0
//-*****************************************************************************
void simpleTestIn( const std::string& iArchiveName )
{
    AbcF::IFactory factory;
    factory.setPolicy( ErrorHandler::kThrowPolicy );

    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive( iArchiveName, coreType );

    /*
               x1
           /   |   \
         x2    x3   x2a (x2a is an instance targeting x2)
          |    |
         x4    x5    (x5 is an instance targeting x4)
        / |
      g1  g2
          |
          g5
    */

    // an archive has a single top object which contains all its children
    IObject topObject = archive.getTop();

    IObject x1( topObject, "x1" );
    TESTING_ASSERT( x1 != 0 );

    //
    // Verify the target path
    IObject x2( x1, "x2" );
    TESTING_ASSERT( x2.valid() );
    TESTING_ASSERT( !x2.isInstanceDescendant() );

    IObject x4( x2, "x4" );
    TESTING_ASSERT( x4.valid() );
    TESTING_ASSERT( !x4.isInstanceDescendant() );

    int numChildren = x4.getNumChildren();
    TESTING_ASSERT( numChildren == 2 );
    TESTING_ASSERT( x4.getParent().getFullName() == x2.getFullName() );

    IObject g1( x4.getChild(0) );
    TESTING_ASSERT( g1 != 0 );
    TESTING_ASSERT( g1.getName() == "g1" );
    TESTING_ASSERT( !g1.isInstanceDescendant() );
    TESTING_ASSERT( g1.getParent() != 0 );
    TESTING_ASSERT( g1.getParent().getFullName() == x4.getFullName() );

    IObject g2( x4.getChild(1) );
    TESTING_ASSERT( g2 != 0 );
    TESTING_ASSERT( g2.getName() == "g2" );
    TESTING_ASSERT( !g2.isInstanceDescendant() );
    TESTING_ASSERT( g2.getParent() != 0 );
    TESTING_ASSERT( g2.getParent().getFullName() == x4.getFullName() );

    IObject g5( g2.getChild(0) );
    TESTING_ASSERT( g5 != 0 );
    TESTING_ASSERT( g5.getName() == "g5" );
    TESTING_ASSERT( !g5.isInstanceDescendant() );
    TESTING_ASSERT( g5.getParent() != 0 );
    TESTING_ASSERT( g5.getParent().getFullName() == g2.getFullName() );

    //
    // Verify the instance path
    IObject x3( x1, "x3" );
    TESTING_ASSERT( x3 != 0 );

    IObject x5( x3, "x5" );
    TESTING_ASSERT( x5 != 0 );

    TESTING_ASSERT( x5.isInstanceDescendant() );
    TESTING_ASSERT( x5.isInstanceRoot() );
    TESTING_ASSERT( x5.instanceSourcePath() == x4.getFullName() );

    numChildren = x5.getNumChildren();
    TESTING_ASSERT( numChildren == 2 );
    TESTING_ASSERT( x5.getParent().getFullName() == x3.getFullName() );

    IObject g1p( x5.getChild(0) );
    TESTING_ASSERT( g1p != 0 );
    TESTING_ASSERT( g1p.getName() == "g1" );
    TESTING_ASSERT( g1p.isInstanceDescendant() );
    TESTING_ASSERT( !g1p.isInstanceRoot() );
    TESTING_ASSERT( g1p.getParent() != 0 );
    TESTING_ASSERT( g1p.getParent().getFullName() == x5.getFullName() );

    IObject g2p( x5.getChild(1) );
    TESTING_ASSERT( g2p != 0 );
    TESTING_ASSERT( g2p.getName() == "g2" );
    TESTING_ASSERT( g2p.isInstanceDescendant() );
    TESTING_ASSERT( !g2p.isInstanceRoot() );
    TESTING_ASSERT( g2p.getParent() != 0 );
    TESTING_ASSERT( g2p.getParent().getFullName() == x5.getFullName() );

    IObject g5p( g2p.getChild(0) );
    TESTING_ASSERT( g5p != 0 );
    TESTING_ASSERT( g5p.getName() == "g5" );
    TESTING_ASSERT( g5p.isInstanceDescendant() );
    TESTING_ASSERT( !g5p.isInstanceRoot() );
    TESTING_ASSERT( g5p.getParent() != 0 );
    TESTING_ASSERT( g5p.getParent().getFullName() == g2p.getFullName() );

    // test x2a
    IObject x2a( x1, "x2a" );
    TESTING_ASSERT( x2a.valid() );
    TESTING_ASSERT( x2a.isInstanceDescendant() );
    TESTING_ASSERT( x2a.isInstanceRoot() );
    TESTING_ASSERT( x2a.instanceSourcePath() == x2.getFullName() );
    TESTING_ASSERT( x2a.getNumChildren() == 1 );

    IObject x2aParent = x2a.getParent();
    TESTING_ASSERT( x2aParent.getFullName() == "/x1" );
    TESTING_ASSERT( !x2aParent.isInstanceDescendant() );
}
예제 #10
0
//-*****************************************************************************
void simpleTestIn( const std::string &iArchiveName, bool useOgawa)
{
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(iArchiveName, coreType);
    TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) ||
                    (!useOgawa && coreType == AbcF::IFactory::kHDF5) );

    IObject archiveTop = archive.getTop();

    IObject ac0( archiveTop, "ac0" );
    IObject acc0( ac0, "acc0" );

    IObject ac1( archiveTop, "ac1" );

    IInt32ArrayProperty ac1iap0( ac1.getProperties(), "iap0" );
    const AbcA::PropertyHeader * iap0Header =
        ac1.getProperties().getPropertyHeader( "iap0" );
    TESTING_ASSERT( IInt32ArrayProperty::matches( *iap0Header ) );
    TESTING_ASSERT( OInt32ArrayProperty::matches( *iap0Header ) );
    TESTING_ASSERT( ! IFloatArrayProperty::matches( *iap0Header ) );
    TESTING_ASSERT( ! IV3fArrayProperty::matches( *iap0Header ) );

    ISampleSelector ac1iap0iss;

    AbcA::index_t sampIdx = ac1iap0iss.getIndex( ac1iap0.getTimeSampling(),
        ac1iap0.getNumSamples() );

    std::cout << "sampIdx: " << sampIdx << std::endl;


    // an object contains a single compound property that contains all
    // sub-properties; all property access is through that.
    ICompoundProperty ac0Props = ac0.getProperties();

    ICompoundProperty acc0Props = acc0.getProperties();

    TESTING_ASSERT( ac0.getNumChildren() == 1 );
    TESTING_ASSERT( ac0Props.getNumProperties() == 4 );

    TESTING_ASSERT( acc0.getNumChildren() == 0 );
    TESTING_ASSERT( acc0Props.getNumProperties() == 6 );


    std::cout << "ac0 has " << ac0.getNumChildren() << " children and "
              << ac0Props.getNumProperties() << " properties." << std::endl;

    std::cout << "acc0 has " << acc0.getNumChildren() << " children and "
              << acc0Props.getNumProperties() << " properties." << std::endl;

    for ( size_t i = 0 ; i < acc0Props.getNumProperties() ; ++i )
    {
        std::cout << "acc0.getPropertyHeader( " << i << " ).getName(): "
                  << acc0Props.getPropertyHeader( i ).getName() << std::endl;
    }

    ICompoundProperty acc0CProp0( acc0Props, "acc0CProp0" );

    IInt32Property acc0cp0ip0( acc0CProp0, "acc0cp0ip0" );
    IInt32Property acc0cp0ip1( acc0CProp0, "acc0cp0ip1" );

    int acc0cp0ip0val = acc0cp0ip0.getValue();
    int acc0cp0ip1val = acc0cp0ip1.getValue();

    TESTING_ASSERT( acc0cp0ip0val == 0 );
    TESTING_ASSERT( acc0cp0ip1val == 1 );

    std::cout << "acc0cp0ip0 is " << acc0cp0ip0val << std::endl;
    std::cout << "acc0cp0ip1 is " << acc0cp0ip1val << std::endl;


    IV3fProperty ac0V3fp0( ac0Props, "ac0V3fp0", kStrictMatching );
    IN3fProperty ac0N3fp0( ac0Props, "ac0N3fp0", kStrictMatching );
    IP3fProperty ac0P3fp0( ac0Props, "ac0P3fp0", kStrictMatching );

    // we expect this to throw when doing strict matching
    TESTING_ASSERT_THROW (
        IP3fProperty( ac0Props, "ac0N3fp0", kStrictMatching ),
        Alembic::Util::Exception );

    IInt32Property acc0ip0( acc0Props, "acc0ip0" );

    IBoolProperty acc0bp0( acc0Props, "acc0bp0" );

    TESTING_ASSERT( ! acc0bp0.getValue() );

    std::cout << "bool scalar property acc0bp0 is false!  Huzzah!"
              << std::endl;

    TESTING_ASSERT( acc0ip0.getValue() == 99 );

    TESTING_ASSERT( ac0V3fp0.getValue() == scalarV3fval );
    TESTING_ASSERT( ac0N3fp0.getValue() == scalarV3fval );
    TESTING_ASSERT( ac0P3fp0.getValue() == scalarV3fval );

    std::cout << "acc0ip0 is " << acc0ip0.getValue() << std::endl;

    std::cout << "ac0V3fp0 is " << ac0V3fp0.getValue() << std::endl;

    IV3fArrayProperty acc0V3fap0( acc0Props, "acc0V3fap0", kStrictMatching );
    const AbcA::PropertyHeader * acc0V3fap0Header =
        acc0Props.getPropertyHeader( "acc0V3fap0" );
    TESTING_ASSERT( OV3fArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( IV3fArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( ! OFloatArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( ! IFloatArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( ! IInt32ArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( ! IP3fArrayProperty::matches( *acc0V3fap0Header ) );
    TESTING_ASSERT( ! IV3fProperty::matches( *acc0V3fap0Header ) );
    V3fArraySamplePtr acc0V3fap0SampPtr;

    IP3fArrayProperty acc0P3fap0( acc0Props, "acc0P3fap0", kStrictMatching );
    const AbcA::PropertyHeader * acc0P3fap0Header =
        acc0Props.getPropertyHeader( "acc0P3fap0" );
    TESTING_ASSERT( OP3fArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( IP3fArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( ! OFloatArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( ! IFloatArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( ! IInt32ArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( ! IV3fArrayProperty::matches( *acc0P3fap0Header ) );
    TESTING_ASSERT( ! IP3fProperty::matches( *acc0P3fap0Header ) );
    P3fArraySamplePtr acc0P3fap0SampPtr;

    IN3fArrayProperty acc0N3fap0( acc0Props, "acc0N3fap0", kStrictMatching );
    const AbcA::PropertyHeader * acc0N3fap0Header =
        acc0Props.getPropertyHeader( "acc0N3fap0" );
    TESTING_ASSERT( ON3fArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( IN3fArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( ! OFloatArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( ! IFloatArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( ! IInt32ArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( ! IV3fArrayProperty::matches( *acc0N3fap0Header ) );
    TESTING_ASSERT( ! IP3fProperty::matches( *acc0N3fap0Header ) );
    N3fArraySamplePtr acc0N3fap0SampPtr;

    TESTING_ASSERT_THROW (
        IP3fProperty( ac0Props, "acc0V3fap0", kStrictMatching ),
        Alembic::Util::Exception );

    IInt32ArrayProperty ac0iap0( ac0Props, "ac0iap0" );
    Int32ArraySamplePtr ac0iap0SampPtr;

    const size_t numReadV3fSamps = acc0V3fap0.getNumSamples();
    const size_t numReadN3fSamps = acc0N3fap0.getNumSamples();
    const size_t numReadP3fSamps = acc0P3fap0.getNumSamples();
    const size_t numReadIntSamps = ac0iap0.getNumSamples();

    TESTING_ASSERT( numReadIntSamps == numIntSamps );
    TESTING_ASSERT( numReadV3fSamps == numV3fSamps );
    TESTING_ASSERT( numReadN3fSamps == numV3fSamps );
    TESTING_ASSERT( numReadP3fSamps == numV3fSamps );

    std::cout << "acc0V3fap0 has " << numReadV3fSamps << " samples." << std::endl;

    std::cout << "ac0iap0 has " << numReadIntSamps << " samples." << std::endl;

    // first the V3f array property
    for ( size_t i = 0 ; i < numV3fSamps ; ++i )
    {
        acc0V3fap0.get( acc0V3fap0SampPtr, i );
        acc0N3fap0.get( acc0N3fap0SampPtr, i );
        acc0P3fap0.get( acc0P3fap0SampPtr, i );

        size_t numPoints = acc0V3fap0SampPtr->size();
        chrono_t time = acc0V3fap0.getTimeSampling()->getSampleTime( i );

        chrono_t compTime = v3fStartTime + ( i * dt );

        TESTING_ASSERT( numPoints == numV3fPoints );
        TESTING_ASSERT( numPoints == acc0N3fap0SampPtr->size() );
        TESTING_ASSERT( numPoints == acc0P3fap0SampPtr->size() );
        TESTING_ASSERT( Imath::equalWithAbsError( time, compTime,
                                                  CHRONO_EPSILON ) );

        float32_t elementVal = i + time;

        TESTING_ASSERT( (*acc0V3fap0SampPtr)[0][0] == elementVal );
        TESTING_ASSERT( (*acc0N3fap0SampPtr)[0][0] == elementVal );
        TESTING_ASSERT( (*acc0P3fap0SampPtr)[0][0] == elementVal );

        std::cout << "acc0V3fap0 at sample " << i << " is at time "
                  << time
                  << " and has " << numPoints << " points "
                  << " with the values:" << std::endl;

        for ( size_t j = 0 ; j < numPoints ; ++j )
        {
            std::cout << (*acc0V3fap0SampPtr)[j] << ", ";
        }

        std::cout << std::endl << std::endl;
    }

    // now the int array property
    for ( size_t i = 0 ; i < numIntSamps ; ++i )
    {
        ac0iap0.get( ac0iap0SampPtr, i );

        size_t numPoints = ac0iap0SampPtr->size();
        chrono_t time = ac0iap0.getTimeSampling()->getSampleTime( i );

        chrono_t compTime = intStartTime + ( i * dt );

        TESTING_ASSERT( Imath::equalWithAbsError( time, compTime,
                                                  CHRONO_EPSILON ) );

        TESTING_ASSERT( numPoints == numIntPoints );

        std::cout << "ac0iap0 at sample " << i << " is at time "
                  << time
                  << " and has " << numPoints << " points"
                  << " with the values:" << std::endl;

        for ( size_t j = 0 ; j < numPoints ; ++j )
        {
            Alembic::Util::int32_t val = (*ac0iap0SampPtr)[j];

            TESTING_ASSERT( val == ( Alembic::Util::int32_t ) ( i + j ) );

            std::cout << val << ", ";
        }

        std::cout << std::endl << std::endl;
    }
}
예제 #11
0
void readProperty(const std::string &archiveName)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    std::cout  << "Reading " << archiveName << std::endl;
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const unsigned int numChildren = archiveTop.getNumChildren();
    ABCA_ASSERT( numChildren == 1, "Wrong number of children (expected 3)");
    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;


    // Iterate through them, print out their names
    IObject child( archiveTop, archiveTop.getChildHeader(0).getName() );
    std::cout << "  " << child.getName();

    // Properties
    ICompoundProperty props = child.getProperties();
    size_t numProperties = props.getNumProperties(); // only top-level props
    ABCA_ASSERT( numProperties == 1,
                 "Expected 1 property, found " << numProperties);
    std::cout << " has a simple property";

    std::vector<std::string> propNames(1);
    propNames[0] = props.getPropertyHeader(0).getName();
    std::cout << " named " << propNames[0] << std::endl;


    PropertyType pType = props.getPropertyHeader(0).getPropertyType();
    ABCA_ASSERT( pType == kScalarProperty,
                 "Expected a scalar property, but didn't find one" );

    DataType dType = props.getPropertyHeader(0).getDataType();
    ABCA_ASSERT( dType.getPod() == kFloat64POD,
                 "Expected a double (kFloat64POD) property, but didn't"
                 " find one" );

    // We know this is a scalar property (I'm eliding the if/else
    //  statements required to recognize this)
    IDoubleProperty mass( props, propNames[0] );
    size_t numSamples = mass.getNumSamples();
    std::cout << ".. it has " << numSamples << " samples" << std::endl;
    ABCA_ASSERT( numSamples == 5, "Expected 5 samples, found " << numSamples );

    std::cout << "..with values: ";
    for (unsigned int ss=0; ss<numSamples; ss++)
    {
        ISampleSelector iss( (index_t) ss);
        printSampleValue( mass, iss );

        double massDiff = mass.getValue( iss ) -  (33.0 + 0.1*ss);
        ABCA_ASSERT( fabs(massDiff) < 1e-12, "Incorrect sample value read" );
    }
    std::cout << std::endl;

    // Done - the archive closes itself
}
void emptyAndValueTest(const std::string &archiveName, bool useOgawa)
{
    std::vector<std::string> strVec;
    strVec.push_back( "potato" );

    std::vector<C3f> colorVec;
    colorVec.push_back( C3f( 0.0, 0.5, 0.75 ) );

    std::vector<Alembic::Util::int32_t> intVec;
    intVec.push_back(42);

    StringArraySample strSamp( strVec );
    C3fArraySample colorSamp( colorVec );
    Int32ArraySample intSamp( intVec );

    StringArraySample emptyStrSamp = StringArraySample::emptySample();
    C3fArraySample emptyColorSamp = C3fArraySample::emptySample();
    Int32ArraySample emptyIntSamp = Int32ArraySample::emptySample();

    {
        OArchive archive;
        if (useOgawa)
        {
            archive = OArchive( Alembic::AbcCoreOgawa::WriteArchive(),
                archiveName );
        }
        else
        {
            archive = OArchive( Alembic::AbcCoreHDF5::WriteArchive(),
                archiveName );
        }

        OCompoundProperty root = archive.getTop().getProperties();
        OC3fArrayProperty colorProp( root, "colors" );
        OInt32ArrayProperty numProp( root, "numbers" );
        AbcA::MetaData md;
        SetReference( md );
        OStringArrayProperty strProp( root, "strings", md );
        TESTING_ASSERT( isReference( strProp.getHeader() ) );

        colorProp.set( emptyColorSamp );
        colorProp.set( colorSamp );
        colorProp.set( emptyColorSamp );
        colorProp.set( colorSamp );

        numProp.set( emptyIntSamp );
        numProp.set( intSamp );
        numProp.set( emptyIntSamp );
        numProp.set( intSamp );

        strProp.set( emptyStrSamp );
        strProp.set( strSamp );
        strProp.set( emptyStrSamp );
        strProp.set( strSamp );
    }

    {
        StringArraySamplePtr strSampPtr;
        C3fArraySamplePtr colorSampPtr;
        Int32ArraySamplePtr intSampPtr;

        AbcF::IFactory factory;
        factory.setPolicy(  ErrorHandler::kThrowPolicy );
        AbcF::IFactory::CoreType coreType;
        IArchive archive = factory.getArchive(archiveName, coreType);
        TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) ||
                        (!useOgawa && coreType == AbcF::IFactory::kHDF5) );

        ICompoundProperty root = archive.getTop().getProperties();
        IC3fArrayProperty colorProp( root, "colors" );
        IInt32ArrayProperty numProp( root, "numbers" );
        IStringArrayProperty strProp( root, "strings" );
        TESTING_ASSERT( isReference( strProp.getHeader() ) );

        TESTING_ASSERT( colorProp.getNumSamples() == 4 );
        TESTING_ASSERT( strProp.getNumSamples() == 4 );
        TESTING_ASSERT( numProp.getNumSamples() == 4 );

        colorProp.get( colorSampPtr, 0 );
        strProp.get( strSampPtr, 0 );
        numProp.get( intSampPtr, 0 );
        TESTING_ASSERT( colorSampPtr->size() == 0 );
        TESTING_ASSERT( strSampPtr->size() == 0 );
        TESTING_ASSERT( intSampPtr->size() == 0 );

        colorProp.get( colorSampPtr, 2 );
        strProp.get( strSampPtr, 2 );
        numProp.get( intSampPtr, 2 );
        TESTING_ASSERT( colorSampPtr->size() == 0 );
        TESTING_ASSERT( strSampPtr->size() == 0 );
        TESTING_ASSERT( intSampPtr->size() == 0 );

        colorProp.get( colorSampPtr, 1 );
        strProp.get( strSampPtr, 1 );
        numProp.get( intSampPtr, 1 );
        TESTING_ASSERT( colorSampPtr->size() == 1 &&
            colorSamp[0] == ( *colorSampPtr )[0] );
        TESTING_ASSERT( strSampPtr->size() == 1 &&
            strSamp[0] == ( *strSampPtr )[0] );
        TESTING_ASSERT( intSampPtr->size() == 1 &&
            intSamp[0] == ( *intSampPtr )[0] );

        colorProp.get( colorSampPtr, 3 );
        strProp.get( strSampPtr, 3 );
        numProp.get( intSampPtr, 3 );
        TESTING_ASSERT( colorSampPtr->size() == 1 &&
            colorSamp[0] == ( *colorSampPtr )[0] );
        TESTING_ASSERT( strSampPtr->size() == 1 &&
            strSamp[0] == ( *strSampPtr )[0] );
        TESTING_ASSERT( intSampPtr->size() == 1 &&
            intSamp[0] == ( *intSampPtr )[0] );
    }
}
void readWriteColorArrayProperty(const std::string &archiveName, bool useOgawa)
{

    {
        OArchive archive;
        if (useOgawa)
        {
            archive = OArchive( Alembic::AbcCoreOgawa::WriteArchive(),
                archiveName, ErrorHandler::kThrowPolicy );
        }
        else
        {
            archive = OArchive( Alembic::AbcCoreHDF5::WriteArchive(),
                archiveName, ErrorHandler::kThrowPolicy );
        }

        OObject archiveTop = archive.getTop();

        OObject child( archiveTop, "test" );
        OCompoundProperty childProps = child.getProperties();

        OC3fArrayProperty shades( childProps, "shades", 0 );

        std::vector < C3f > grays(8);
        grays[0].x = 0.0; grays[0].y = 0.0; grays[0].z = 0.0;
        grays[1].x = 0.125; grays[1].y = 0.125; grays[1].z = 0.125;

        grays[2].x = 0.25; grays[2].y = 0.25; grays[2].z = 0.25;
        grays[3].x = 0.375; grays[3].y = 0.375; grays[3].z = 0.375;

        grays[4].x = 0.5; grays[4].y = 0.5; grays[4].z = 0.5;
        grays[5].x = 0.625; grays[5].y = 0.625; grays[5].z = 0.625;

        grays[6].x = 0.75; grays[6].y = 0.75; grays[6].z = 0.75;
        grays[7].x = 0.875; grays[7].y = 0.875; grays[7].z = 0.875;

        // let's write 4 different color3f[2]
        Dimensions d;
        d.setRank(2);
        d[0] = 2;
        d[1] = 4;

        C3fArraySample cas(&(grays.front()), d);
        shades.set(cas);
    }
    {
        // now read it
        AbcF::IFactory factory;
        factory.setPolicy(  ErrorHandler::kThrowPolicy );
        AbcF::IFactory::CoreType coreType;
        IArchive archive = factory.getArchive(archiveName, coreType);
        TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) ||
                        (!useOgawa && coreType == AbcF::IFactory::kHDF5) );

        IObject archiveTop = archive.getTop();

        IObject child( archiveTop, archiveTop.getChildHeader(0).getName() );
        ICompoundProperty props = child.getProperties();
        IC3fArrayProperty shades( props, "shades" );

        C3fArraySamplePtr samplePtr;
        shades.get( samplePtr );

        ABCA_ASSERT( samplePtr->getDimensions().rank() == 2,
                     "Incorrect rank on the sample." );

        ABCA_ASSERT( samplePtr->getDimensions().numPoints() == 8,
                     "Incorrect number of total points." );

        ABCA_ASSERT( samplePtr->getDimensions()[0] == 2,
                     "Incorrect size on dimension 0." );

        ABCA_ASSERT( samplePtr->getDimensions()[1] == 4,
                     "Incorrect size on dimension 1." );

        Alembic::Util::Dimensions dims;
        shades.getDimensions( dims );

        ABCA_ASSERT( dims.rank() == 2,
                     "Incorrect rank on the sample." );

        ABCA_ASSERT( dims.numPoints() == 8,
                     "Incorrect number of total points." );

        ABCA_ASSERT( dims[0] == 2,
                     "Incorrect size on dimension 0." );

        ABCA_ASSERT( dims[1] == 4,
                     "Incorrect size on dimension 1." );

        for (size_t i = 0; i < 8; ++i)
        {
            ABCA_ASSERT( (*samplePtr)[i].x == i/8.0 &&
                         (*samplePtr)[i].x == (*samplePtr)[i].y &&
                         (*samplePtr)[i].x == (*samplePtr)[i].z,
                         "Color [" << i << "] is incorrect.");
        }

        double start, end;
        GetArchiveStartAndEndTime( archive, start, end );

        TESTING_ASSERT( almostEqual(start, 0.0) );
        TESTING_ASSERT( almostEqual(end, 0.0) );
    }
}
void readV3fArrayProperty(const std::string &archiveName, bool useOgawa)
{
    // Open an existing archive for reading. Indicate that we want
    //   Alembic to throw exceptions on errors.
    std::cout  << "Reading " << archiveName << std::endl;
    AbcF::IFactory factory;
    factory.setPolicy(  ErrorHandler::kThrowPolicy );
    AbcF::IFactory::CoreType coreType;
    IArchive archive = factory.getArchive(archiveName, coreType);
    TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) ||
                    (!useOgawa && coreType == AbcF::IFactory::kHDF5) );

    IObject archiveTop = archive.getTop();

    // Determine the number of (top level) children the archive has
    const unsigned int numChildren =  archiveTop.getNumChildren();
    ABCA_ASSERT( numChildren == 1, "Wrong number of children (expected 1)");
    std::cout << "The archive has " << numChildren << " children:"
              << std::endl;

    // Iterate through them, print out their names
    IObject child( archiveTop, archiveTop.getChildHeader(0).getName() );
    std::cout << "  named '" << child.getName() << "'";

    // Properties
    ICompoundProperty props = child.getProperties();
    size_t numProperties = props.getNumProperties();  // only top-level props
    ABCA_ASSERT( numProperties == 1,
                 "Expected 1 property, found " << numProperties);
    std::cout << " with one property";

    std::vector<std::string> propNames(1);
    propNames[0] = props.getPropertyHeader(0).getName();
    std::cout << " named '" << propNames[0] << "'" << std::endl;


    PropertyType pType = props.getPropertyHeader(0).getPropertyType();
    ABCA_ASSERT( pType == kArrayProperty,
                 "Expected an array property, but didn't find one" );

    std::cout << " which is an array property";

    DataType dType = props.getPropertyHeader(0).getDataType();
    ABCA_ASSERT( dType.getPod() == kFloat32POD,
                 "Expected an v3f property, but didn't find one" );


    // We know this is an array property (I'm eliding the if/else
    //  statements required to recognize and handle this properly)
    IV3fArrayProperty positions( props, propNames[0] );
    size_t numSamples = positions.getNumSamples();
    std::cout << ".. it has " << numSamples << " samples" << std::endl;
    ABCA_ASSERT( numSamples == 5, "Expected 5 samples, found " << numSamples );

    TimeSamplingPtr ts = positions.getTimeSampling();
    std::cout << "..with time/value pairs: " << std::endl;;
    for (unsigned int ss=0; ss<numSamples; ss++)
    {
        std::cout << "   ";
        ISampleSelector iss( (index_t) ss);
        std::cout << ts->getSampleTime( (index_t) ss ) << " / ";

        V3fArraySamplePtr samplePtr;
        positions.get( samplePtr, iss );
        std::cout << "[ ";
        size_t numPoints = samplePtr->size();
        for ( size_t jj=0 ; jj<numPoints ; jj++ )
            std::cout << (*samplePtr)[jj] << " ";
        std::cout << "]" << std::endl;

        if (ss == 2) // no entries in sample #2
        {
            ABCA_ASSERT( numPoints == 0,
                         "Expected an empty sample, but found " << numPoints
                         << " entries." );
        }
        else
        {
            for ( size_t jj=0 ; jj<numPoints ; jj++ )
                ABCA_ASSERT( (*samplePtr)[jj] == g_vectors[jj],
                             "Incorrect value read from archive." );
        }

    }
    ABCA_ASSERT(
        archive.getMaxNumSamplesForTimeSamplingIndex(1) == (index_t) numSamples,
        "Incorrect number of max samples in readV3fArrayProperty." );
    std::cout << std::endl;
    // Done - the archive closes itself

    double start, end;
    GetArchiveStartAndEndTime( archive, start, end );

    TESTING_ASSERT( almostEqual(start, 123.0) );
    TESTING_ASSERT( almostEqual(end, 123.0 + 4.0 / 24.0) );
}
예제 #15
0
MStatus AlembicNode::compute(const MPlug & plug, MDataBlock & dataBlock)
{
    MStatus status;

    // update the frame number to be imported
    MDataHandle speedHandle = dataBlock.inputValue(mSpeedAttr, &status);
    double speed = speedHandle.asDouble();

    MDataHandle offsetHandle = dataBlock.inputValue(mOffsetAttr, &status);
    double offset = offsetHandle.asDouble();

    MDataHandle timeHandle = dataBlock.inputValue(mTimeAttr, &status);
    MTime t = timeHandle.asTime();
    double inputTime = t.as(MTime::kSeconds);

    double fps = getFPS();

    // scale and offset inputTime.
    inputTime = computeAdjustedTime(inputTime, speed, offset/fps);

    // this should be done only once per file
	if (mFileInitialized == false)
	{
		mFileInitialized = true;

		//Get list of input filenames
		MFnDependencyNode depNode(thisMObject());
		MPlug layerFilesPlug = depNode.findPlug("abc_layerFiles");
		MFnStringArrayData fnSAD( layerFilesPlug.asMObject() );
		MStringArray storedFilenames = fnSAD.array();

		//Legacy support for single-filename input
		if( storedFilenames.length() == 0 )
		{
			MFileObject fileObject;
			MDataHandle dataHandle = dataBlock.inputValue(mAbcFileNameAttr);
			fileObject.setRawFullName(dataHandle.asString());
			MString fileName = fileObject.resolvedFullName();
			storedFilenames.append( fileName );
		}

		std::vector<std::string> abcFilenames;
		for(unsigned int i = 0; i < storedFilenames.length(); i++)
			abcFilenames.push_back( storedFilenames[i].asChar() );

		Alembic::Abc::IArchive archive;
		Alembic::AbcCoreFactory::IFactory factory;
		factory.setPolicy(Alembic::Abc::ErrorHandler::kQuietNoopPolicy);

		archive = factory.getArchive( abcFilenames );

		if (!archive.valid())
		{
			MString theError = "Error opening these alembic files: ";

			const unsigned int numFilenames = storedFilenames.length();
			for( unsigned int i = 0; i < numFilenames; i++ )
			{
				theError += storedFilenames[ i ];

				if( i != (numFilenames - 1) )
					theError += ", ";
			}

			printError(theError);
		}

		// initialize some flags for plug update
		mSubDInitialized = false;
		mPolyInitialized = false;

		// When an alembic cache will be imported at the first time using
		// AbcImport, we need to set mIncludeFilterAttr (filterHandle) to be
		// mIncludeFilterString for later use. When we save a maya scene(.ma)
		// mIncludeFilterAttr will be saved. Then when we load the saved
		// .ma file, mIncludeFilterString will be set to be mIncludeFilterAttr.
		MDataHandle includeFilterHandle =
						dataBlock.inputValue(mIncludeFilterAttr, &status);
		MString& includeFilterString = includeFilterHandle.asString();

	   if (mIncludeFilterString.length() > 0)
		{
			includeFilterHandle.set(mIncludeFilterString);
			dataBlock.setClean(mIncludeFilterAttr);
		}
		else if (includeFilterString.length() > 0)
		{
			mIncludeFilterString = includeFilterString;
		}

		MDataHandle excludeFilterHandle =
						dataBlock.inputValue(mExcludeFilterAttr, &status);
		MString& excludeFilterString = excludeFilterHandle.asString();

	   if (mExcludeFilterString.length() > 0)
		{
			excludeFilterHandle.set(mExcludeFilterString);
			dataBlock.setClean(mExcludeFilterAttr);
		}
		else if (excludeFilterString.length() > 0)
		{
			mExcludeFilterString = excludeFilterString;
		}


		MFnDependencyNode dep(thisMObject());
		MPlug allSetsPlug = dep.findPlug("allColorSets");
		CreateSceneVisitor visitor(inputTime, !allSetsPlug.isNull(),
			MObject::kNullObj, CreateSceneVisitor::NONE, "",
			mIncludeFilterString, mExcludeFilterString);

		visitor.walk(archive);

		if (visitor.hasSampledData())
		{
			// information retrieved from the hierarchy traversal
			// and given to AlembicNode to provide update
			visitor.getData(mData);
			mData.getFrameRange(mSequenceStartTime, mSequenceEndTime);
			MDataHandle startFrameHandle = dataBlock.inputValue(mStartFrameAttr,
																&status);
			startFrameHandle.set(mSequenceStartTime*fps);
			MDataHandle endFrameHandle = dataBlock.inputValue(mEndFrameAttr,
																&status);
			endFrameHandle.set(mSequenceEndTime*fps);
		}
	}

    // Retime
    MDataHandle cycleHandle = dataBlock.inputValue(mCycleTypeAttr, &status);
    short playType = cycleHandle.asShort();
    inputTime = computeRetime(inputTime, mSequenceStartTime, mSequenceEndTime,
                              playType);

    clamp<double>(mSequenceStartTime, mSequenceEndTime, inputTime);

    // update only when the time lapse is big enough
    if (fabs(inputTime - mCurTime) > 0.00001)
    {
        mOutRead = std::vector<bool>(mOutRead.size(), false);
        mCurTime = inputTime;
    }

    if (plug == mOutPropArrayAttr)
    {

        if (mOutRead[0])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[0] = true;

        unsigned int propSize =
            static_cast<unsigned int>(mData.mPropList.size());

        if (propSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPropArrayAttr, &status);

            unsigned int outHandleIndex = 0;
            MDataHandle outHandle;

            // for all of the nodes with sampled attributes
            for (unsigned int i = 0; i < propSize; i++)
            {
                // only use the handle if it matches the index.
                // The index wont line up in the sparse case so we
                // can just skip that element.
                if (outArrayHandle.elementIndex() == outHandleIndex++)
                {
                    outHandle = outArrayHandle.outputValue();
                }
                else
                {
                    continue;
                }

                if (mData.mPropList[i].mArray.valid())
                {
                    readProp(mCurTime, mData.mPropList[i].mArray, outHandle);
                }
                else if (mData.mPropList[i].mScalar.valid())
                {
                    // for visibility only
                    if (mData.mPropList[i].mScalar.getName() ==
                        Alembic::AbcGeom::kVisibilityPropertyName)
                    {
                        Alembic::Util::int8_t visVal = 1;
                        mData.mPropList[i].mScalar.get(&visVal,
                            Alembic::Abc::ISampleSelector(mCurTime,
                                Alembic::Abc::ISampleSelector::kNearIndex ));
                        outHandle.setGenericBool(visVal != 0, false);
                    }
                    else
                    {
                        // for all scalar props
                        readProp(mCurTime, mData.mPropList[i].mScalar, outHandle);
                    }
                }
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
        }

    }
    else if (plug == mOutTransOpArrayAttr )
    {
        if (mOutRead[1])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[1] = true;

        unsigned int xformSize =
            static_cast<unsigned int>(mData.mXformList.size());

        if (xformSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutTransOpArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutTransOpArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < xformSize; i++)
            {
                std::vector<double> sampleList;

                if (mData.mIsComplexXform[i])
                {
                    readComplex(mCurTime, mData.mXformList[i], sampleList);
                }
                else
                {
                    Alembic::AbcGeom::XformSample samp;
                    read(mCurTime, mData.mXformList[i], sampleList, samp);
                }

                unsigned int sampleSize = (unsigned int)sampleList.size();

                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutLocatorPosScaleArrayAttr )
    {
        if (mOutRead[8])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[8] = true;

        unsigned int locSize =
            static_cast<unsigned int>(mData.mLocList.size());

        if (locSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutLocatorPosScaleArrayAttr, &status);

            MPlug arrayPlug(thisMObject(), mOutLocatorPosScaleArrayAttr);

            MDataHandle outHandle;
            unsigned int outHandleIndex = 0;

            for (unsigned int i = 0; i < locSize; i++)
            {
                std::vector< double > sampleList;
                read(mCurTime, mData.mLocList[i], sampleList);

                unsigned int sampleSize = (unsigned int)sampleList.size();
                for (unsigned int j = 0; j < sampleSize; j++)
                {
                    // only use the handle if it matches the index.
                    // The index wont line up in the sparse case so we
                    // can just skip that element.
                    if (outArrayHandle.elementIndex() == outHandleIndex++)
                    {
                        outHandle = outArrayHandle.outputValue(&status);
                    }
                    else
                        continue;

                    outArrayHandle.next();
                    outHandle.set(sampleList[j]);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutSubDArrayAttr)
    {
        if (mOutRead[2])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutSubDArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[2] = true;

        unsigned int subDSize =
            static_cast<unsigned int>(mData.mSubDList.size());

        if (subDSize > 0)
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < subDSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readSubD(mCurTime, fnMesh, obj, mData.mSubDList[j],
                        mSubDInitialized);
                    outHandle.set(obj);
                }
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutSubDArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue();
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mSubDInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutPolyArrayAttr)
    {
        if (mOutRead[3])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[3] = true;

        unsigned int polySize =
            static_cast<unsigned int>(mData.mPolyMeshList.size());

        if (polySize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutPolyArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < polySize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kMesh))
                {
                    MFnMesh fnMesh(obj);
                    readPoly(mCurTime, fnMesh, obj, mData.mPolyMeshList[j],
                        mPolyInitialized);
                    outHandle.set(obj);
                }
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
        // for the case where we don't have any nodes, we want to make sure
        // to push out empty meshes on our connections, this can happen if
        // the input file was offlined, currently we only need to do this for
        // meshes as Nurbs, curves, and the other channels don't crash Maya
        else
        {
            MArrayDataHandle outArrayHandle = dataBlock.outputValue(
                mOutPolyArrayAttr, &status);

            if (outArrayHandle.elementCount() > 0)
            {
                do
                {
                    MDataHandle outHandle = outArrayHandle.outputValue(&status);
                    MObject obj = outHandle.data();
                    if (obj.hasFn(MFn::kMesh))
                    {
                        MFloatPointArray emptyVerts;
                        MIntArray emptyCounts;
                        MIntArray emptyConnects;
                        MFnMesh emptyMesh;
                        emptyMesh.create(0, 0, emptyVerts, emptyCounts,
                            emptyConnects, obj);
                        outHandle.set(obj);
                    }
                }
                while (outArrayHandle.next() == MS::kSuccess);
            }
            mPolyInitialized = true;
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutCameraArrayAttr)
    {
        if (mOutRead[4])
        {
            dataBlock.setClean(plug);
            return MS::kSuccess;
        }

        mOutRead[4] = true;

        unsigned int cameraSize =
            static_cast<unsigned int>(mData.mCameraList.size());

        if (cameraSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutCameraArrayAttr, &status);
            MPlug arrayPlug(thisMObject(), mOutCameraArrayAttr);
            double angleConversion = 1.0;

            switch (MAngle::uiUnit())
            {
                case MAngle::kRadians:
                    angleConversion = 0.017453292519943295;
                break;
                case MAngle::kAngMinutes:
                    angleConversion = 60.0;
                break;
                case MAngle::kAngSeconds:
                    angleConversion = 3600.0;
                break;
                default:
                break;
            }

            MDataHandle outHandle;
            unsigned int index = 0;

            for (unsigned int cameraIndex = 0; cameraIndex < cameraSize;
                cameraIndex++)
            {
                Alembic::AbcGeom::ICamera & cam =
                    mData.mCameraList[cameraIndex];
                std::vector<double> array;

                read(mCurTime, cam, array);

                for (unsigned int dataIndex = 0; dataIndex < array.size();
                    dataIndex++, index++)
                {
                    // skip over sparse elements
                    if (index != outArrayHandle.elementIndex())
                    {
                        continue;
                    }

                    outHandle = outArrayHandle.outputValue(&status);
                    outArrayHandle.next();

                    // not shutter angle index, so not an angle
                    if (dataIndex != 11)
                    {
                        outHandle.set(array[dataIndex]);
                    }
                    else
                    {
                        outHandle.set(array[dataIndex] * angleConversion);
                    }
                }  // for the per camera data handles
            }  // for each camera
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsSurfaceArrayAttr)
    {
        if (mOutRead[5])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[5] = true;

        unsigned int nSurfaceSize =
            static_cast<unsigned int>(mData.mNurbsList.size());

        if (nSurfaceSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsSurfaceArrayAttr, &status);

            MDataHandle outHandle;

            for (unsigned int j = 0; j < nSurfaceSize; j++)
            {
                // these elements can be sparse if they have been deleted
                if (outArrayHandle.elementIndex() != j)
                    continue;

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();

                MObject obj = outHandle.data();
                if (obj.hasFn(MFn::kNurbsSurface))
                {
                    readNurbs(mCurTime, mData.mNurbsList[j], obj);
                    outHandle.set(obj);
                }
            }
            outArrayHandle.setAllClean();
        }
    }
    else if (plug == mOutNurbsCurveGrpArrayAttr)
    {
        if (mOutRead[6])
        {
            // Reference the output to let EM know we are the writer
            // of the data. EM sets the output to holder and causes
            // race condition when evaluating fan-out destinations.
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            const unsigned int elementCount = outArrayHandle.elementCount();
            for (unsigned int j = 0; j < elementCount; j++)
            {
                outArrayHandle.outputValue().data();
                outArrayHandle.next();
            }
            outArrayHandle.setAllClean();
            return MS::kSuccess;
        }

        mOutRead[6] = true;

        unsigned int nCurveGrpSize =
            static_cast<unsigned int>(mData.mCurvesList.size());

        if (nCurveGrpSize > 0)
        {
            MArrayDataHandle outArrayHandle =
                dataBlock.outputValue(mOutNurbsCurveGrpArrayAttr, &status);
            MDataHandle outHandle;

            std::vector<MObject> curvesObj;
            for (unsigned int i = 0; i < nCurveGrpSize; ++i)
            {
                readCurves(mCurTime, mData.mCurvesList[i],
                    mData.mNumCurves[i], curvesObj);
            }

            std::size_t numChild = curvesObj.size();

            // not the best way to do this
            // only reading bunches of curves based on the connections would be
            // more efficient when there is a bunch of broken connections
            for (unsigned int i = 0; i < numChild; i++)
            {
                if (outArrayHandle.elementIndex() != i)
                {
                    continue;
                }

                outHandle = outArrayHandle.outputValue(&status);
                outArrayHandle.next();
                status = outHandle.set(curvesObj[i]);
            }

            outArrayHandle.setAllClean();
        }
    }
    else
    {
        return MS::kUnknownParameter;
    }

    dataBlock.setClean(plug);
    return status;
}
예제 #16
0
//-*****************************************************************************
int main( int argc, char *argv[] )
{
    bool opt_all = false;
    bool opt_meta = false;
    std::string desc( "abctree [OPTION] FILE[/NAME]\n"
    "  -a          include properties listings\n"
    "  -h, --help  prints this help message\n"
    "  -m          print metadata\n"
    );

    // check for min args
    if ( argc < 2 ) {
        std::cout << desc << std::endl;
        return 0;
    };

    // parse args
    std::vector<std::string> arguments(argv, argv + argc);
    std::vector<std::string> options;
    std::vector<std::string> files;

    // separate file args from option args 
    for ( std::size_t i = 1; i < arguments.size(); i++ ) {
        if ( arguments[ i ].substr( 0, 1 ) == "-" )
            options.push_back( arguments[ i ] );
        else
            files.push_back( arguments[ i ] );
    }

    // help
    if ( argc < 2 ||
         optionExists( options, "h" ) ||
         optionExists( options, "help" )
       ) {
        std::cout << desc << std::endl;
        return 0;
    };

    // set some flags
    opt_all = optionExists( options, "a");
    opt_meta = optionExists( options, "m");

    // open each file
    size_t count = 0;
    for ( std::size_t i = 0; i < files.size(); i++ ) {
        if ( files.size() > 1 )
            std::cout << BOLD << files[i] << ':' << RESETCOLOR << std::endl;

        std::stringstream ss( files[i] );
        std::stringstream fp;
        std::string segment;
        std::vector<std::string> seglist;

        /* 
         * separate file and object paths, e.g.
         *
         *   ../dir1/foo.abc/bar/baz
         *   \_____________/\______/
         *        file         obj
         */
        int j = 0;
        while ( std::getline( ss, segment, '/' ) ) {
            if ( !isFile ( fp.str() ) ) {
                if ( j != 0 )
                    fp << "/";
                fp << segment;
            } else {
                seglist.push_back( segment );
            }
            ++j;
        }

        // open the iarchive
        Abc::IArchive archive;
        AbcF::IFactory factory;
        factory.setPolicy(Abc::ErrorHandler::kQuietNoopPolicy);
        AbcF::IFactory::CoreType coreType;
        archive = factory.getArchive(std::string( fp.str() ), coreType);

        // display file metadata 
        if ( opt_meta ) {
            std::cout  << "Using "
                       << Alembic::AbcCoreAbstract::GetLibraryVersion ()
                       << std::endl;;

            std::string appName;
            std::string libraryVersionString;
            Alembic::Util::uint32_t libraryVersion;
            std::string whenWritten;
            std::string userDescription;
            std::string coreName;
            GetArchiveInfo (archive,
                            appName,
                            libraryVersionString,
                            libraryVersion,
                            whenWritten,
                            userDescription);

            if ( coreType == AbcF::IFactory::kOgawa ) {
                coreName = "Ogawa";
            } else if ( coreType == AbcF::IFactory::kHDF5 ) {
                coreName = "HDF5";
            } else {
                coreName = "Unknown";
            };

            if ( appName != "" ) {
                std::cout << "  file written by: " << appName << std::endl;
                std::cout << "  using Alembic : " << libraryVersionString << std::endl;
                std::cout << "  written on : " << whenWritten << std::endl;
                std::cout << "  user description : " << userDescription << std::endl;
            } else {
                std::cout << "  (file doesn't have any ArchiveInfo)"
                          << std::endl;
            }
            std::cout << "  core type : " << coreName << std::endl;
        };

        // walk object hierarchy and find valid objects
        AbcG::IObject test = archive.getTop();
        AbcG::IObject iObj = test;
        while ( test.valid() && seglist.size() > 0 ) {
            test = test.getChild( seglist.front() );
            if ( test.valid() ) {
                iObj = test;
                seglist.erase( seglist.begin() );
            }
        }

        // walk property hierarchy for most recent valid object
        Abc::ICompoundProperty props = iObj.getProperties();
        const Abc::PropertyHeader* header;
        bool found = false;
        for ( std::size_t i = 0; i < seglist.size(); ++i ) {
            header = props.getPropertyHeader( seglist[i] );
            if ( header && header->isCompound() ) {
                Abc::ICompoundProperty ptest( props, header->getName() );
                if ( ptest.valid() ) {
                    props = ptest;
                    found = true;
                }
            } else if ( header && header->isSimple() ) {
                found = true;
            } else {
                std::cout << seglist[i] 
                          << ": Invalid object or property" 
                          << std::endl;
                return 1;
            }
        }

        // walk the archive tree
        if ( found ) 
            if ( header->isCompound() )
                tree( props );
            else
                tree( Abc::IScalarProperty( props, header->getName() ) );
        else
            tree( iObj, opt_all );

        ++count;
    }

    return 0;
}