//-***************************************************************************** void getABCTimeSpan(IArchive archive, chrono_t& first, chrono_t& last) { // TO DO: Is the childBounds property reliable to get the full archive's span? if (!archive.valid()) return; IObject archiveTop = archive.getTop(); if ( archiveTop.getProperties().getPropertyHeader( ".childBnds" ) != NULL ) { // Try to get timing from childBounds first IBox3dProperty childbnds = Alembic::Abc::IBox3dProperty( archive.getTop().getProperties(), ".childBnds", ErrorHandler::kQuietNoopPolicy); TimeSamplingPtr ts = childbnds.getTimeSampling(); first = std::min(first, ts->getSampleTime(0) ); last = std::max(last, ts->getSampleTime(childbnds.getNumSamples()-1) ); return; } unsigned int numChildren = archiveTop.getNumChildren(); for (unsigned i=0; i<numChildren; ++i) // Visit every object to get its first and last sample { IObject obj( archiveTop.getChild( i )); getObjectTimeSpan(obj, first, last, true); } }
//-***************************************************************************** void layerTest() { std::string fileName = "objectLayer1.abc"; std::string fileName2 = "objectLayer2.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName ); OObject child( archive.getTop(), "child" ); OObject childCool( child, "cool" ); OObject childGuy( child, "guy" ); OObject childA( archive.getTop(), "childA" ); OObject childAA( childA, "A" ); } { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName2 ); OObject child( archive.getTop(), "child" ); OObject childCool( child, "cool" ); OObject childGal( child, "gal" ); OObject childA( archive.getTop(), "childB" ); OObject childAA( childA, "B" ); } { std::vector< std::string > files; files.push_back( fileName ); files.push_back( fileName2 ); Alembic::AbcCoreFactory::IFactory factory; IArchive archive = factory.getArchive( files ); // child, childA, childB TESTING_ASSERT( archive.getTop().getNumChildren() == 3 ); IObject child = archive.getTop().getChild("child"); TESTING_ASSERT( child.getNumChildren() == 3 ); TESTING_ASSERT( child.getChild("cool").valid() ); TESTING_ASSERT( child.getChild("cool").getNumChildren() == 0 ); TESTING_ASSERT( child.getChild("guy").valid() ); TESTING_ASSERT( child.getChild("guy").getNumChildren() == 0 ); TESTING_ASSERT( child.getChild("gal").valid() ); TESTING_ASSERT( child.getChild("gal").getNumChildren() == 0 ); IObject childA = archive.getTop().getChild("childA"); TESTING_ASSERT( childA.getNumChildren() == 1 ); TESTING_ASSERT( childA.getChild("A").valid() ); TESTING_ASSERT( childA.getChild("A").getNumChildren() == 0 ); IObject childB = archive.getTop().getChild("childB"); TESTING_ASSERT( childB.getNumChildren() == 1 ); TESTING_ASSERT( childB.getChild("B").valid() ); TESTING_ASSERT( childB.getChild("B").getNumChildren() == 0 ); } }
//-***************************************************************************** void pruneTest() { std::string fileName = "objectPrune1.abc"; std::string fileName2 = "objectPrune2.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName ); OObject child( archive.getTop(), "child" ); OObject childCool( child, "cool" ); OObject childGuy( child, "guy" ); OObject childA( archive.getTop(), "childA" ); OObject childAA( childA, "A" ); OObject childB( archive.getTop(), "childB" ); OObject childBB( childB, "B" ); } { MetaData md; Alembic::AbcCoreLayer::SetPrune( md, true ); OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName2 ); OObject child( archive.getTop(), "child" ); OObject childGuy( child, "guy", md ); OObject childA( archive.getTop(), "childA" ); OObject childAA( childA, "A", md ); OObject childAB( childA, "B", md ); OObject childB( archive.getTop(), "childB", md ); } { std::vector< std::string > files; files.push_back( fileName ); files.push_back( fileName2 ); Alembic::AbcCoreFactory::IFactory factory; IArchive archive = factory.getArchive( files ); // child, childA, childB TESTING_ASSERT( archive.getTop().getNumChildren() == 2 ); IObject child = archive.getTop().getChild("child"); TESTING_ASSERT( child.getNumChildren() == 1 ); TESTING_ASSERT( child.getChild("cool").valid() ); TESTING_ASSERT( child.getChild("cool").getNumChildren() == 0 ); IObject childA = archive.getTop().getChild("childA"); TESTING_ASSERT( childA.getNumChildren() == 0 ); } }
void ABCReadGeo::updateTableKnob() { p_tableKnobI->deleteAllItems(); p_tableKnobI->reset(); if (filename()[0] == '\0') { return; } IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), filename(), Abc::ErrorHandler::kQuietNoopPolicy ); if (!archive.valid()) { return; } IObject archiveTop = archive.getTop(); std::vector<Alembic::AbcGeom::IObject> _objs; getABCGeos(archiveTop, _objs); int obj = 0; for( std::vector<Alembic::AbcGeom::IObject>::const_iterator iObj( _objs.begin() ); iObj != _objs.end(); ++iObj ) { p_tableKnobI->addRow(obj); p_tableKnobI->setCellString(obj,0,iObj->getName()); p_tableKnobI->setCellBool(obj,1,true); obj++; } }
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 }
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 scopingTest(bool useOgawa) { { OObject top; { OArchive archive; if (useOgawa) { archive = CreateArchiveWithInfo( Alembic::AbcCoreOgawa::WriteArchive(), "archiveScopeTest.abc", "Alembic test", "", MetaData() ); } else { archive = CreateArchiveWithInfo( Alembic::AbcCoreHDF5::WriteArchive(), "archiveScopeTest.abc", "Alembic test", "", MetaData() ); } top = archive.getTop(); } OObject childA( top, "a"); OObject childB( top, "b"); ODoubleProperty prop(top.getProperties(), "prop", 0); TESTING_ASSERT(prop.getObject().getArchive().getName() == "archiveScopeTest.abc"); } { IObject top; { AbcF::IFactory factory; AbcF::IFactory::CoreType coreType; IArchive archive = factory.getArchive("archiveScopeTest.abc", coreType); TESTING_ASSERT( (useOgawa && coreType == AbcF::IFactory::kOgawa) || (!useOgawa && coreType == AbcF::IFactory::kHDF5) ); top = archive.getTop(); double start, end; GetArchiveStartAndEndTime( archive, start, end ); TESTING_ASSERT( start == DBL_MAX && end == -DBL_MAX ); } TESTING_ASSERT(top.getNumChildren() == 2 ); TESTING_ASSERT(top.getChildHeader("a") != NULL); TESTING_ASSERT(top.getChildHeader("b") != NULL); TESTING_ASSERT( ! top.getParent().valid() ); TESTING_ASSERT( top.getArchive().getName() == "archiveScopeTest.abc"); IScalarProperty prop(top.getProperties(), "prop"); TESTING_ASSERT(prop.valid()); TESTING_ASSERT(prop.getObject().getArchive().getName() == "archiveScopeTest.abc"); } }
//-***************************************************************************** void getABCTimeSpan(IArchive archive, chrono_t& first, chrono_t& last) { // TO DO: Is the childBounds property reliable to get the full archive's span? if (!archive.valid()) return; IObject archiveTop = archive.getTop(); unsigned int numChildren = archiveTop.getNumChildren(); for (unsigned i=0; i<numChildren; ++i) { IObject obj( archiveTop.getChild( i )); getObjectTimeSpan(obj, first, last, true); } }
//-***************************************************************************** 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 ); }
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 }
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 }
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" ); } }
//-***************************************************************************** //-***************************************************************************** // 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 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() ); }
/*virtual*/ void ABCReadGeo::create_geometry(Scene& scene, GeometryList& out) { if (filename()[0] == '\0') { out.delete_objects(); return; } IArchive archive( Alembic::AbcCoreHDF5::ReadArchive(), filename(),//archiveName, Abc::ErrorHandler::kQuietNoopPolicy ); if (!archive.valid()) { std::cout << "error reading archive" << std::endl; error("Unable to read file"); return; } IObject archiveTop = archive.getTop(); std::vector<Alembic::AbcGeom::IObject> _objs; getABCGeos(archiveTop, _objs); // current Time to sample from chrono_t curTime = m_sampleFrame / _FPS; if ( rebuild(Mask_Primitives)) { out.delete_objects(); } int obj = 0; for( std::vector<Alembic::AbcGeom::IObject>::const_iterator iObj( _objs.begin() ); iObj != _objs.end(); ++iObj ) { // Leave an empty obj if knob is unchecked if (!active_objs[obj] ) { out.add_object(obj); PointList& points = *out.writable_points(obj); points.resize(0); out[obj].delete_group_attribute(Group_Vertices,kUVAttrName, VECTOR4_ATTRIB); obj++; continue; } if ( rebuild(Mask_Primitives)) { out.add_object(obj); if (bbox_objs[obj]) { //(bbox_mode) { buildBboxPrimitives(out, obj); } else { buildABCPrimitives(out, obj, *iObj, curTime); } } if ( rebuild(Mask_Points)) { PointList& points = *out.writable_points(obj); if (bbox_objs[obj]) { //(bbox_mode) { Imath::Box3d bbox = getBounds(*iObj, curTime); points.resize(8); IObject iObj_copy(*iObj); Matrix4 xf = getConcatMatrix(iObj_copy,curTime, interpolate !=0); // for some reason getParent() won't take a const IObject, hence the copy... // Add bbox corners for (unsigned i = 0; i < 8; i++) { Vector3 pt((i&4)>>2 ? bbox.max.x : bbox.min.x, (i&2)>>1 ? bbox.max.y : bbox.min.y, (i%2) ? bbox.max.z : bbox.min.z ); points[i] = xf.transform(pt); } } else{ writePoints(*iObj, points, curTime, interpolate !=0); } } if ( rebuild(Mask_Attributes)) { if (bbox_objs[obj]) { //(bbox_mode) out[obj].delete_group_attribute(Group_Vertices,kUVAttrName, VECTOR4_ATTRIB); } else { // set UVs Attribute* UV = out.writable_attribute(obj, Group_Vertices, kUVAttrName, VECTOR4_ATTRIB); IV2fGeomParam uvParam = getUVsParam(*iObj); setUVs(out[obj], uvParam, UV, curTime); // set Normals IN3fGeomParam nParam = getNsParam(*iObj); if (nParam.valid()) { Attribute* N = out.writable_attribute(obj, Group_Vertices, kNormalAttrName, NORMAL_ATTRIB); setNormals(out[obj], nParam, N, curTime); } } } obj++; }
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 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; } }
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) ); }
//-***************************************************************************** void diabolicalInstance( const std::string& iArchiveName, bool useOgawa ) { /* a0 b0 (points to a0) / | a1 b1 (points to a1) / | a2 b2 (points to b2) */ { OArchive archive; if (useOgawa) { archive = OArchive( Alembic::AbcCoreOgawa::WriteArchive(), iArchiveName, ErrorHandler::kThrowPolicy ); } else { archive = OArchive( Alembic::AbcCoreHDF5::WriteArchive(), iArchiveName, ErrorHandler::kThrowPolicy ); } OObject topobj = archive.getTop(); OObject a0( topobj, "a0" ); TESTING_ASSERT( topobj.addChildInstance( a0, "b0" ) ); OObject a1( a0, "a1" ); TESTING_ASSERT( a0.addChildInstance( a1, "b1" ) ); OObject a2( a1, "a2" ); TESTING_ASSERT( a1.addChildInstance( a2, "b2" ) ); } { AbcF::IFactory factory; IArchive archive = factory.getArchive( iArchiveName ); IObject topObject = archive.getTop(); IObject a0( topObject.getChild(0) ); TESTING_ASSERT( !a0.isInstanceDescendant() ); TESTING_ASSERT( a0.getFullName() == "/a0" ); TESTING_ASSERT( !a0.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0.getParent().getFullName() == "/" ); IObject b0( topObject.getChild(1) ); TESTING_ASSERT( b0.isInstanceDescendant() ); TESTING_ASSERT( b0.getName() == "b0" ); TESTING_ASSERT( b0.getFullName() == "/b0" ); TESTING_ASSERT( !b0.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0.getParent().getFullName() == "/" ); IObject a0a1( a0.getChild(0) ); TESTING_ASSERT( !a0a1.isInstanceDescendant() ); TESTING_ASSERT( a0a1.getName() == "a1" ); TESTING_ASSERT( a0a1.getFullName() == "/a0/a1" ); TESTING_ASSERT( !a0a1.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0a1.getParent().getName() == "a0" ); TESTING_ASSERT( a0a1.getParent().getFullName() == "/a0" ); IObject a0b1( a0.getChild(1) ); TESTING_ASSERT( a0b1.isInstanceDescendant() ); TESTING_ASSERT( a0b1.getName() == "b1" ); TESTING_ASSERT( a0b1.getFullName() == "/a0/b1" ); TESTING_ASSERT( !a0b1.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0b1.getParent().getName() == "a0" ); TESTING_ASSERT( a0b1.getParent().getFullName() == "/a0" ); IObject b0a1( b0.getChild(0) ); TESTING_ASSERT( b0a1.isInstanceDescendant() ); TESTING_ASSERT( b0a1.getParent().isInstanceDescendant() ); IObject b0b1( b0.getChild(1) ); TESTING_ASSERT( b0b1.isInstanceDescendant() ); TESTING_ASSERT( b0b1.getName() == "b1" ); TESTING_ASSERT( b0b1.getFullName() == "/b0/b1" ); TESTING_ASSERT( b0b1.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0b1.getParent().getName() == "b0" ); TESTING_ASSERT( b0b1.getParent().getFullName() == "/b0" ); IObject a0a1a2( a0a1.getChild(0) ); TESTING_ASSERT( !a0a1a2.isInstanceDescendant() ); TESTING_ASSERT( a0a1a2.getName() == "a2" ); TESTING_ASSERT( a0a1a2.getFullName() == "/a0/a1/a2" ); TESTING_ASSERT( !a0a1a2.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0a1a2.getParent().getName() == "a1" ); TESTING_ASSERT( a0a1a2.getParent().getFullName() == "/a0/a1" ); TESTING_ASSERT( !a0a1a2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( a0a1a2.getParent().getParent().getName() == "a0" ); TESTING_ASSERT( a0a1a2.getParent().getParent().getFullName() == "/a0" ); IObject a0a1b2( a0a1.getChild(1) ); TESTING_ASSERT( a0a1b2.isInstanceDescendant() ); TESTING_ASSERT( a0a1b2.getName() == "b2" ); TESTING_ASSERT( a0a1b2.getFullName() == "/a0/a1/b2" ); TESTING_ASSERT( !a0a1b2.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0a1b2.getParent().getName() == "a1" ); TESTING_ASSERT( a0a1b2.getParent().getFullName() == "/a0/a1" ); TESTING_ASSERT( !a0a1b2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( a0a1b2.getParent().getParent().getName() == "a0" ); TESTING_ASSERT( a0a1b2.getParent().getParent().getFullName() == "/a0" ); IObject a0b1a2( a0b1.getChild(0) ); TESTING_ASSERT( a0b1a2.isInstanceDescendant() ); TESTING_ASSERT( a0b1a2.getName() == "a2" ); TESTING_ASSERT( a0b1a2.getFullName() == "/a0/b1/a2" ); TESTING_ASSERT( a0b1a2.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0b1a2.getParent().getName() == "b1" ); TESTING_ASSERT( a0b1a2.getParent().getFullName() == "/a0/b1" ); TESTING_ASSERT( !a0b1a2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( a0b1a2.getParent().getParent().getName() == "a0" ); TESTING_ASSERT( a0b1a2.getParent().getParent().getFullName() == "/a0" ); IObject a0b1b2( a0b1.getChild(1) ); TESTING_ASSERT( a0b1b2.isInstanceDescendant() ); TESTING_ASSERT( a0b1b2.getName() == "b2" ); TESTING_ASSERT( a0b1b2.getFullName() == "/a0/b1/b2" ); TESTING_ASSERT( a0b1b2.getParent().isInstanceDescendant() ); TESTING_ASSERT( a0b1b2.getParent().getName() == "b1" ); TESTING_ASSERT( a0b1b2.getParent().getFullName() == "/a0/b1" ); TESTING_ASSERT( !a0b1b2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( a0b1b2.getParent().getParent().getName() == "a0" ); TESTING_ASSERT( a0b1b2.getParent().getParent().getFullName() == "/a0" ); IObject b0a1a2( b0a1.getChild(0) ); TESTING_ASSERT( b0a1a2.isInstanceDescendant() ); TESTING_ASSERT( b0a1a2.getName() == "a2" ); TESTING_ASSERT( b0a1a2.getFullName() == "/b0/a1/a2" ); TESTING_ASSERT( b0a1a2.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0a1a2.getParent().getName() == "a1" ); TESTING_ASSERT( b0a1a2.getParent().getFullName() == "/b0/a1" ); TESTING_ASSERT( b0a1a2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( b0a1a2.getParent().getParent().getName() == "b0" ); TESTING_ASSERT( b0a1a2.getParent().getParent().getFullName() == "/b0" ); IObject b0a1b2( b0a1.getChild(1) ); TESTING_ASSERT( b0a1b2.isInstanceDescendant() ); TESTING_ASSERT( b0a1b2.getName() == "b2" ); TESTING_ASSERT( b0a1b2.getFullName() == "/b0/a1/b2" ); TESTING_ASSERT( b0a1b2.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0a1b2.getParent().getName() == "a1" ); TESTING_ASSERT( b0a1b2.getParent().getFullName() == "/b0/a1" ); TESTING_ASSERT( b0a1b2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( b0a1b2.getParent().getParent().getName() == "b0" ); TESTING_ASSERT( b0a1b2.getParent().getParent().getFullName() == "/b0" ); IObject b0b1a2( b0b1.getChild(0) ); TESTING_ASSERT( b0b1a2.isInstanceDescendant() ); TESTING_ASSERT( b0b1a2.getName() == "a2" ); TESTING_ASSERT( b0b1a2.getFullName() == "/b0/b1/a2" ); TESTING_ASSERT( b0b1a2.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0b1a2.getParent().getName() == "b1" ); TESTING_ASSERT( b0b1a2.getParent().getFullName() == "/b0/b1" ); TESTING_ASSERT( b0b1a2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( b0b1a2.getParent().getParent().getName() == "b0" ); TESTING_ASSERT( b0b1a2.getParent().getParent().getFullName() == "/b0" ); IObject b0b1b2( b0b1.getChild(1) ); TESTING_ASSERT( b0b1b2.isInstanceDescendant() ); TESTING_ASSERT( b0b1b2.getName() == "b2" ); TESTING_ASSERT( b0b1b2.getFullName() == "/b0/b1/b2" ); TESTING_ASSERT( b0b1b2.getParent().isInstanceDescendant() ); TESTING_ASSERT( b0b1b2.getParent().getName() == "b1" ); TESTING_ASSERT( b0b1b2.getParent().getFullName() == "/b0/b1" ); TESTING_ASSERT( b0b1b2.getParent().getParent().isInstanceDescendant() ); TESTING_ASSERT( b0b1b2.getParent().getParent().getName() == "b0" ); TESTING_ASSERT( b0b1b2.getParent().getParent().getFullName() == "/b0" ); } }
//-***************************************************************************** void replaceTest() { std::string fileName = "objectReplace1.abc"; std::string fileName2 = "objectReplace2.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName ); OObject child( archive.getTop(), "child" ); OObject childCool( child, "cool" ); OObject childCooler( childCool, "cooler" ); OObject childGuy( child, "guy" ); OObject childGuyA( childGuy, "A" ); OObject childA( archive.getTop(), "childA" ); OObject childAA( childA, "A" ); OObject childB( archive.getTop(), "childB" ); OObject childBB( childB, "B" ); } { MetaData md; Alembic::AbcCoreLayer::SetReplace( md, true ); OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), fileName2 ); OObject child( archive.getTop(), "child" ); OObject childGuy( child, "guy", md ); OObject childCool( child, "cool", md ); OObject childCoolA( childCool, "A" ); OObject childCoolB( childCool, "B", md ); OObject childA( archive.getTop(), "childA", md ); OObject childB( archive.getTop(), "childB", md ); OObject childBA( childB, "A", md ); OObject childBC( childB, "C", md ); OObject childBCA( childBC, "A", md ); } { std::vector< std::string > files; files.push_back( fileName ); files.push_back( fileName2 ); Alembic::AbcCoreFactory::IFactory factory; IArchive archive = factory.getArchive( files ); IObject root = archive.getTop(); // child, childA, childB TESTING_ASSERT( root.getNumChildren() == 3 ); IObject child( root, "child" ); TESTING_ASSERT( child.getNumChildren() == 2 ); TESTING_ASSERT( IObject( child, "cool" ).valid() ); TESTING_ASSERT( IObject( child, "guy" ).valid() ); TESTING_ASSERT( IObject( child, "cool" ).getNumChildren() == 2 ); TESTING_ASSERT( IObject( child, "guy" ).getNumChildren() == 0 ); IObject childCool( child, "cool" ); TESTING_ASSERT( IObject( childCool, "A" ).valid() ); TESTING_ASSERT( IObject( childCool, "A" ).getNumChildren() == 0 ); TESTING_ASSERT( IObject( childCool, "B" ).valid() ); TESTING_ASSERT( IObject( childCool, "B" ).getNumChildren() == 0 ); IObject childA( root, "childA" ); TESTING_ASSERT( childA.getNumChildren() == 0 ); IObject childB( root, "childB" ); TESTING_ASSERT( childB.getNumChildren() == 2 ); TESTING_ASSERT( IObject( childB, "A" ).valid() ); TESTING_ASSERT( IObject( childB, "C" ).valid() ); TESTING_ASSERT( IObject( childB, "A" ).getNumChildren() == 0 ); TESTING_ASSERT( IObject( childB, "C" ).getNumChildren() == 1 ); IObject childBC( childB, "C" ); TESTING_ASSERT( IObject( childBC, "A" ).valid() ); TESTING_ASSERT( IObject( childBC, "A" ).getNumChildren() == 0 ); } }