//-***************************************************************************** void ReadTestArchive( const std::string &iArchiveName ) { // When opening an archive for reading, you can pass in a pointer to // an AbcA::ReadArraySampleCache, but if you don't, it will construct one // for you by default. If you don't want to cache, just pass in NULL // as the second argument. Alembic::AbcCoreHDF5::ReadArchive ar; AbcA::ArchiveReaderPtr arkive = ar( iArchiveName ); // Just stashing away a compound property reader pointer; we know the last // child object in our hierarchy has all the properties, because we created // it in the WriteTestArchive function. AbcA::CompoundPropertyReaderPtr fcProps; // Now do a depth-first traversal of our archive; this is a little ugly AbcA::ObjectReaderPtr tmpOrp1; AbcA::ObjectReaderPtr tmpOrp2 = arkive->getTop(); while ( true ) { tmpOrp1 = tmpOrp2; if ( tmpOrp1->getNumChildren() < 1 ) { std::cout << "Found my last lonely child, named " << tmpOrp1->getFullName() << std::endl; fcProps = tmpOrp1->getProperties(); std::cout << "It has " << fcProps->getNumProperties() << " sub-properties." << std::endl; break; } tmpOrp2 = tmpOrp1->getChild( 0 ); } // OK, fcProps is a shared pointer to the compound property reader that // was in the last child object of the archive. Let's get the simple // properties out of it. AbcA::ScalarPropertyReaderPtr sProp; AbcA::ArrayPropertyReaderPtr aProp0; AbcA::ArrayPropertyReaderPtr aProp1; for ( size_t i = 0 ; i < fcProps->getNumProperties() ; ++i ) { AbcA::BasePropertyReaderPtr bp = fcProps->getProperty( i ); std::cout << "Found " << bp->getName() << std::endl; if ( bp->isScalar() ) { sProp = bp->asScalarPtr(); std::cout << "sProp has " << sProp->getNumSamples() << " samples." << std::endl; } if ( bp->isArray() && bp->getName() == "secondInt32ArrayProp" ) { aProp1 = bp->asArrayPtr(); std::cout << "aProp1 has " << aProp1->getNumSamples() << " samples." << std::endl; } if ( bp->isArray() && bp->getName() == "firstInt32ArrayProp" ) { aProp0 = bp->asArrayPtr(); std::cout << "aProp0 has " << aProp0->getNumSamples() << " samples." << std::endl; } } // OK, now we have pointers to the two properties, one scalar, the other // array. Let's read the scalar one first. for ( size_t i = 0 ; i < sProp->getNumSamples() ; ++i ) { float32_t sVal = 0; sProp->getSample( i, (void*)(&sVal) ); TESTING_ASSERT( sVal == 42.0 ); std::cout << sProp->getName() << " at sample " << i << " has the value " << sVal << std::endl << std::endl; } // OK, now the first int array property. AbcA::ArraySamplePtr samp; std::cout << "FIRST INT ARRAY PROPERTY (Cyclic time sampling)" << std::endl; for ( size_t i = 0 ; i < aProp0->getNumSamples() ; ++i ) { aProp0->getSample( i, samp ); const AbcA::TimeSampling ts = aProp0->getTimeSampling(); size_t numPoints = samp->getDimensions().numPoints(); TESTING_ASSERT( (AbcA::chrono_t)i == ts.getSampleTime( i ) ); std::cout << "At Sample " << i << ", " << aProp0->getName() << " is at time " << ts.getSampleTime( i ) << " and has " << numPoints << " points, with the values: " << std::endl; int32_t *vals = (int32_t*)(samp->getData()); for ( size_t j = 0 ; j < numPoints ; ++j ) { TESTING_ASSERT( vals[j] == i + j ); std::cout << j << ": " << vals[j] << ", "; } std::cout << std::endl << std::endl; samp->reset(); } // now the second int array std::cout << "SECOND INT ARRAY PROPERTY (Acyclic time sampling)" << std::endl; for ( size_t i = 0 ; i < aProp1->getNumSamples() ; ++i ) { aProp1->getSample( i, samp ); const AbcA::TimeSampling ts = aProp1->getTimeSampling(); size_t numPoints = samp->getDimensions().numPoints(); std::cout << "At Sample " << i << ", " << aProp1->getName() << " is at time " << ts.getSampleTime( i ) << " and has " << numPoints << " points," << std::endl << "with the values: " << std::endl; int32_t *vals = (int32_t*)(samp->getData()); for ( size_t j = 0 ; j < numPoints ; ++j ) { TESTING_ASSERT( vals[j] == i + j ); std::cout << j << ": " << vals[j] << ", "; } std::cout << std::endl << std::endl; samp->reset(); } }
//-***************************************************************************** void testTimeSamplingScalar() { std::string archiveName = "timeSamplingScalar.abc"; { A5::WriteArchive w; AbcA::ArchiveWriterPtr a = w(archiveName, AbcA::MetaData()); AbcA::ObjectWriterPtr archive = a->getTop(); AbcA::CompoundPropertyWriterPtr parent = archive->getProperties(); // illegal time value TESTING_ASSERT_THROW(parent->createScalarProperty("uniform", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kInt32POD, 1), 42), Alembic::Util::Exception); std::vector < double > timeSamps(1,-4.0); AbcA::TimeSamplingType tst(3.0); AbcA::TimeSampling ts(tst, timeSamps); uint32_t tsid = a->addTimeSampling(ts); AbcA::ScalarPropertyWriterPtr swp = parent->createScalarProperty("uniform", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kInt32POD, 1), tsid); Alembic::Util::int32_t i = 0; swp->setSample(&i); i+=3; swp->setSample(&i); i+=3; swp->setSample(&i); timeSamps.clear(); timeSamps.push_back(4.0); timeSamps.push_back(4.25); timeSamps.push_back(4.5); tst = AbcA::TimeSamplingType(3, 2.0); ts = AbcA::TimeSampling(tst, timeSamps); tsid = a->addTimeSampling(ts); AbcA::ScalarPropertyWriterPtr swp2 = parent->createScalarProperty("cyclic", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kUint32POD, 1), tsid); Alembic::Util::uint32_t ui = 0; swp2->setSample(&ui); ui++; swp2->setSample(&ui); ui++; swp2->setSample(&ui); ui++; swp2->setSample(&ui); ui++; swp2->setSample(&ui); ui++; swp2->setSample(&ui); timeSamps.clear(); timeSamps.push_back(-17.0); timeSamps.push_back(32.0); timeSamps.push_back(50.0); timeSamps.push_back(60.2); timeSamps.push_back(101.1); timeSamps.push_back(700.0); timeSamps.push_back(747.0); tst = AbcA::TimeSamplingType(AbcA::TimeSamplingType::kAcyclic); ts = AbcA::TimeSampling(tst, timeSamps); tsid = a->addTimeSampling(ts); AbcA::ScalarPropertyWriterPtr swp3 = parent->createScalarProperty("acyclic", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kUint16POD, 1), tsid); Alembic::Util::uint16_t s = 0; swp3->setSample(&s); s++; swp3->setSample(&s); s++; swp3->setSample(&s); s++; swp3->setSample(&s); s++; swp3->setSample(&s); s++; swp3->setSample(&s); s++; swp3->setSample(&s); // Setting more than what we have acyclic samples for TESTING_ASSERT_THROW(swp3->setSample(&s), Alembic::Util::Exception); AbcA::ScalarPropertyWriterPtr swp4 = parent->createScalarProperty("identity", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kInt16POD, 1), 0); Alembic::Util::int16_t ss = 35; swp4->setSample(&ss); ss = 37; swp4->setSample(&ss); ss = 1000; swp4->setSample(&ss); timeSamps.clear(); timeSamps.push_back(0.0); tst = AbcA::TimeSamplingType(1.0); ts = AbcA::TimeSampling(tst, timeSamps); tsid = a->addTimeSampling(ts); AbcA::ScalarPropertyWriterPtr swp5 = parent->createScalarProperty("defaultUniform", AbcA::MetaData(), AbcA::DataType(Alembic::Util::kFloat32POD, 1), tsid); Alembic::Util::float32_t f = 0; swp5->setSample(&f); f+=1.1; swp5->setSample(&f); f+=1.1; swp5->setSample(&f); f+=1.1; swp5->setSample(&f); } { A5::ReadArchive r; AbcA::ArchiveReaderPtr a = r( archiveName ); AbcA::ObjectReaderPtr archive = a->getTop(); AbcA::CompoundPropertyReaderPtr parent = archive->getProperties(); TESTING_ASSERT(parent->getNumProperties() == 5); for ( size_t i = 0; i < parent->getNumProperties(); ++i) { AbcA::BasePropertyReaderPtr bp = parent->getProperty( i ); AbcA::ScalarPropertyReaderPtr sp = bp->asScalarPtr(); const AbcA::TimeSamplingPtr t = sp->getTimeSampling(); switch (sp->getDataType().getPod()) { case Alembic::Util::kInt16POD: { // identity TESTING_ASSERT( t->getTimeSamplingType().isUniform() ); } break; case Alembic::Util::kUint16POD: { // acylic TESTING_ASSERT( t->getSampleTime(0) == -17.0 ); TESTING_ASSERT( sp->getNumSamples() == 7); TESTING_ASSERT( t->getTimeSamplingType().isAcyclic() ); TESTING_ASSERT( t->getSampleTime(1) == 32.0 ); TESTING_ASSERT( t->getSampleTime(2) == 50.0 ); TESTING_ASSERT( t->getSampleTime(3) == 60.2 ); TESTING_ASSERT( t->getSampleTime(4) == 101.1 ); TESTING_ASSERT( t->getSampleTime(5) == 700.0 ); TESTING_ASSERT( t->getSampleTime(6) == 747.0 ); TESTING_ASSERT_THROW( t->getSampleTime(7), Alembic::Util::Exception); } break; case Alembic::Util::kFloat32POD: { TESTING_ASSERT( sp->getNumSamples() == 4); TESTING_ASSERT( t->getTimeSamplingType().isUniform() ); TESTING_ASSERT( t->getSampleTime(0) == 0.0 ); TESTING_ASSERT( t->getSampleTime(1) == 1.0 ); TESTING_ASSERT( t->getSampleTime(2) == 2.0 ); TESTING_ASSERT( t->getSampleTime(3) == 3.0 ); } break; case Alembic::Util::kInt32POD: { // uniform TESTING_ASSERT( sp->getNumSamples() == 3); TESTING_ASSERT( t->getTimeSamplingType().isUniform() ); TESTING_ASSERT( t->getSampleTime(0) == -4.0 ); TESTING_ASSERT( t->getSampleTime(1) == -1.0 ); TESTING_ASSERT( t->getSampleTime(2) == 2.0 ); } break; case Alembic::Util::kUint32POD: { // cyclic TESTING_ASSERT( sp->getNumSamples() == 6); TESTING_ASSERT( t->getTimeSamplingType().isCyclic() ); TESTING_ASSERT( t->getSampleTime(0) == 4.0 ); TESTING_ASSERT( t->getSampleTime(1) == 4.25 ); TESTING_ASSERT( t->getSampleTime(2) == 4.5 ); TESTING_ASSERT( t->getSampleTime(3) == 6.0 ); TESTING_ASSERT( t->getSampleTime(4) == 6.25 ); TESTING_ASSERT( t->getSampleTime(5) == 6.5 ); } break; default: TESTING_ASSERT(false); break; } } // for } }