//-***************************************************************************** //-***************************************************************************** // 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; }
void showTimeSampling(IArchive archive) { std::cout<<"num time samplings "<<archive.getNumTimeSamplings()<<std::endl; AbcA::TimeSamplingPtr sampler = archive.getTimeSampling(0); std::cout<<"time sampling[0] "<<sampler->getSampleTime(0)<<std::endl; }