Imath::Box3d AlembicInput::boundAtSample( size_t sampleIndex ) const { const MetaData &md = m_data->object.getMetaData(); if( !m_data->object.getParent() ) { // top of archive return GetIArchiveBounds( *(m_data->archive) ).getValue( ISampleSelector( (index_t)sampleIndex ) ); } else if( IXform::matches( md ) ) { IXform iXForm( m_data->object, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); if( !iXFormSchema.getChildBoundsProperty() ) { throw IECore::Exception( "No stored bounds available" ); } XformSample sample; iXFormSchema.get( sample, ISampleSelector( (index_t)sampleIndex ) ); return sample.getChildBounds(); } else { IGeomBaseObject geomBase( m_data->object, kWrapExisting ); return geomBase.getSchema().getValue( ISampleSelector( (index_t)sampleIndex ) ).getSelfBounds(); } return Box3d(); }
//-***************************************************************************** void xformTreeCreate() { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), "Xform_tree.abc" ); std::vector<OXform> xforms; OObject root( archive, kTop); recurseCreateXform( root, 4, 4, xforms ); std::cout << "Total xforms created " << xforms.size() << std::endl; XformSample samp; XformOp transop( kTranslateOperation, kTranslateHint ); XformOp rotatop( kRotateOperation, kRotateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); samp.addOp( transop, V3d(42.0, 42.0, 42.0) ); samp.addOp( rotatop, V3d(0.0, 0.0, 1.0), 10.0 ); samp.addOp( rotatop, V3d(0.0, 1.0, 0.0), 20.0 ); samp.addOp( rotatop, V3d(1.0, 0.0, 0.0), 30.0 ); samp.addOp( scaleop, V3d(4.0, 4.0, 4.0) ); for (std::vector<OXform>::iterator i = xforms.begin(); i != xforms.end(); ++i) { i->getSchema().set(samp); } }
//-***************************************************************************** void recurseCreateXform(OObject & iParent, int children, int level, std::vector<OXform> & oCreated) { for (int i = 0; i < children; ++i) { std::ostringstream strm; strm << "level" << "_" << i; std::string xformName = strm.str(); OXform xform( iParent, xformName ); XformSample samp; XformOp transop( kTranslateOperation, kTranslateHint ); XformOp rotatop( kRotateOperation, kRotateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); samp.addOp( transop, V3d(0.0, 0.0, 0.0) ); samp.addOp( rotatop, V3d(0.0, 0.0, 1.0), 0.0 ); samp.addOp( rotatop, V3d(0.0, 1.0, 0.0), 0.0 ); samp.addOp( rotatop, V3d(1.0, 0.0, 0.0), 0.0 ); samp.addOp( scaleop, V3d(1.0, 1.0, 1.0) ); xform.getSchema().set(samp); oCreated.push_back( xform ); if ( level > 0 ) { recurseCreateXform( xform, children, level - 1, oCreated ); } } }
Imath::M44d AlembicInput::transformAtTime( double time ) const { M44d result; if( IXform::matches( m_data->object.getMetaData() ) ) { size_t index0, index1; double lerpFactor = sampleIntervalAtTime( time, index0, index1 ); IXform iXForm( m_data->object, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); if( index0 == index1 ) { XformSample sample; iXFormSchema.get( sample, ISampleSelector( (index_t)index0 ) ); result = sample.getMatrix(); } else { XformSample sample0; iXFormSchema.get( sample0, ISampleSelector( (index_t)index0 ) ); XformSample sample1; iXFormSchema.get( sample1, ISampleSelector( (index_t)index1 ) ); if( sample0.getNumOps() != sample1.getNumOps() || sample0.getNumOpChannels() != sample1.getNumOpChannels() ) { throw IECore::Exception( "Unable to interpolate samples of different sizes" ); } XformSample interpolatedSample; for( size_t opIndex = 0; opIndex < sample0.getNumOps(); opIndex++ ) { XformOp op0 = sample0.getOp( opIndex ); XformOp op1 = sample1.getOp( opIndex ); XformOp interpolatedOp( op0.getType(), op0.getHint() ); for( size_t channelIndex = 0; channelIndex < op0.getNumChannels(); channelIndex++ ) { interpolatedOp.setChannelValue( channelIndex, lerp( op0.getChannelValue( channelIndex ), op1.getChannelValue( channelIndex ), lerpFactor ) ); } interpolatedSample.addOp( interpolatedOp ); } result = interpolatedSample.getMatrix(); } } return result; }
//-***************************************************************************** void OWrapExisting() { Alembic::Abc::OArchive archive( Alembic::AbcCoreHDF5::WriteArchive(), "playground_owrap.abc" ); Alembic::Abc::OObject archiveTop = archive.getTop(); Alembic::Util::shared_ptr< Alembic::Abc::OObject > objAPtr = makeXform( archiveTop ); Alembic::Util::shared_ptr< Alembic::Abc::OObject > objBPtr = subdCube( *objAPtr ); // // NOW THE FUN BEGINS // TESTING_ASSERT( Alembic::AbcGeom::OSubD::matches( objBPtr->getHeader() ) ); { Alembic::Util::shared_ptr< Alembic::AbcGeom::OSubD > subdObjPtr = Alembic::Util::dynamic_pointer_cast< Alembic::AbcGeom::OSubD > ( objBPtr ); Alembic::AbcGeom::OSubD subdObj = *subdObjPtr; std::cout << "wrapped-existing subd has " << subdObj.getSchema().getNumSamples() << " num samples." << std::endl; std::vector<V3f> verts( 8, V3f(2.0, 2.0, 2.0 ) ); Alembic::AbcGeom::OSubDSchema::Sample sample; sample.setPositions( Alembic::Abc::V3fArraySample( &(verts[0]), verts.size() ) ); subdObj.getSchema().set( sample ); TESTING_ASSERT( subdObj.getSchema().getNumSamples() == 2 ); } TESTING_ASSERT( Alembic::AbcGeom::OXform::matches( objAPtr->getHeader() ) ); { XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformSample samp; samp.addOp( transop, V3d( 4.0, 5.0, 6.0 ) ); samp.addOp( scaleop, V3d( 8.0, 10.0, 12.0 ) ); Alembic::Util::shared_ptr< Alembic::AbcGeom::OXform > xformObjPtr = Alembic::Util::dynamic_pointer_cast< Alembic::AbcGeom::OXform > ( objAPtr ); Alembic::AbcGeom::OXform xformObj = *xformObjPtr; xformObj.getSchema().set( samp ); TESTING_ASSERT( xformObj.getSchema().getNumSamples() == 2 ); } }
Imath::M44d AlembicInput::transformAtSample( size_t sampleIndex ) const { M44d result; if( IXform::matches( m_data->object.getMetaData() ) ) { IXform iXForm( m_data->object, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); XformSample sample; iXFormSchema.get( sample, ISampleSelector( (index_t)sampleIndex ) ); return sample.getMatrix(); } return result; }
//-***************************************************************************** void accumXform( M44d &xf, IObject obj ) { if ( ISimpleXform::matches( obj.getMetaData() ) ) { ISimpleXform x( obj, kWrapExisting ); xf *= x.getSchema().getValue().getMatrix(); } else if ( IXform::matches( obj.getMetaData() ) ) { IXform x( obj, kWrapExisting ); XformSample xs; x.getSchema().get( xs ); xf *= xs.getMatrix(); } }
IECore::ObjectPtr FromAlembicXFormConverter::doAlembicConversion( const Alembic::Abc::IObject &iObject, const Alembic::Abc::ISampleSelector &sampleSelector, const IECore::CompoundObject *operands ) const { IXform iXForm( iObject, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); XformSample sample; iXFormSchema.get( sample, sampleSelector ); M44d m = sample.getMatrix(); return new M44fData( M44f( m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3] ) ); }
//-***************************************************************************** Alembic::Util::shared_ptr< Alembic::Abc::OObject > makeXform( Alembic::Abc::OObject & parent ) { Alembic::Util::shared_ptr< Alembic::AbcGeom::OXform > xformObjPtr ( new Alembic::AbcGeom::OXform( parent, "myXform" ) ); // add a couple of ops XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformSample samp; samp.addOp( transop, V3d( 1.0, 2.0, 3.0 ) ); samp.addOp( scaleop, V3d( 2.0, 4.0, 6.0 ) ); Alembic::AbcGeom::OXformSchema &schema = xformObjPtr->getSchema(); schema.set( samp ); return xformObjPtr; }
//-***************************************************************************** void IXformSchema::get( XformSample &oSamp, const Abc::ISampleSelector &iSS ) const { ALEMBIC_ABC_SAFE_CALL_BEGIN( "IXformSchema::get()" ); oSamp.reset(); if ( ! valid() ) { return; } oSamp = m_sample; if ( m_inheritsProperty && m_inheritsProperty.getNumSamples() > 0 ) { oSamp.setInheritsXforms( m_inheritsProperty.getValue( iSS ) ); } if ( ! m_valsProperty ) { return; } AbcA::index_t numSamples = 0; if ( m_useArrayProp ) { numSamples = m_valsProperty->asArrayPtr()->getNumSamples(); } else { numSamples = m_valsProperty->asScalarPtr()->getNumSamples(); } if ( numSamples == 0 ) { return; } AbcA::index_t sampIdx = iSS.getIndex( m_valsProperty->getTimeSampling(), numSamples ); if ( sampIdx < 0 ) { return; } this->getChannelValues( sampIdx, oSamp ); ALEMBIC_ABC_SAFE_CALL_END(); }
//-***************************************************************************** bool XformSample::isTopologyEqual( const XformSample & iSample ) { if (getNumOps() != iSample.getNumOps()) { return false; } std::vector<XformOp>::const_iterator opA, opB; for ( opA = m_ops.begin(), opB = iSample.m_ops.begin(); opA != m_ops.end(); ++opA, ++opB ) { if ( opA->getType() != opB->getType() ) { return false; } } return true; }
void accumXform( Imath::M44d &xf, IObject obj, chrono_t curTime, bool interpolate) { if ( IXform::matches( obj.getHeader() ) ) { Imath::M44d mtx; IXform x( obj, kWrapExisting ); XformSample xs; x.getSchema().get( xs ); if (!x.getSchema().isConstant()) { TimeSamplingPtr timeSampler = x.getSchema().getTimeSampling(); if (interpolate) { //std::pair<index_t, chrono_t> lSamp;// = timeSampler->getFloorIndex(curTime, x.getSchema().getNumSamples()); Alembic::AbcCoreAbstract::index_t floorIdx, ceilIdx; double amt = getWeightAndIndex(curTime, timeSampler, x.getSchema().getNumSamples(), floorIdx, ceilIdx); if (amt != 0 && floorIdx != ceilIdx) { const ISampleSelector iss_start(floorIdx);//lSamp.first); Imath::M44d mtx_start = x.getSchema().getValue(iss_start).getMatrix(); //std::pair<index_t, chrono_t> rSamp = timeSampler->getCeilIndex(curTime, x.getSchema().getNumSamples()); const ISampleSelector iss_end(ceilIdx);//rSamp.first); Imath::M44d mtx_end = x.getSchema().getValue(iss_end).getMatrix(); Imath::V3d s_l,s_r,h_l,h_r,t_l,t_r; Imath::Quatd quat_l,quat_r; DecomposeXForm(mtx_start, s_l, h_l, quat_l, t_l); DecomposeXForm(mtx_end, s_r, h_r, quat_r, t_r); if ((quat_l ^ quat_r) < 0) { quat_r = -quat_r; } mtx = RecomposeXForm(Imath::lerp(s_l, s_r, amt), Imath::lerp(h_l, h_r, amt), Imath::slerp(quat_l, quat_r, amt), Imath::lerp(t_l, t_r, amt)); } else { const ISampleSelector iss(curTime); xs = x.getSchema().getValue(iss); mtx = xs.getMatrix(); } } else { // no interpolation, get nearest sample const ISampleSelector iss(curTime); xs = x.getSchema().getValue(iss); mtx = xs.getMatrix(); } } else { mtx = xs.getMatrix(); } xf *= mtx; } }
//-***************************************************************************** void xformOut() { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), "Xform1.abc" ); OXform a( OObject( archive, kTop ), "a" ); OXform b( a, "b" ); OXform c( b, "c" ); OXform d( c, "d" ); OXform e( d, "e" ); OXform f( e, "f" ); OXform g( f, "g" ); XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformOp matrixop( kMatrixOperation, kMatrixHint ); TESTING_ASSERT( a.getSchema().getNumSamples() == 0 ); OBox3dProperty childBounds = a.getSchema().getChildBoundsProperty(); XformSample asamp; for ( size_t i = 0; i < 20; ++i ) { asamp.addOp( transop, V3d( 12.0, i + 42.0, 20.0 ) ); if ( i >= 18 ) { childBounds.set( Abc::Box3d( V3d( -1.0, -1.0, -1.0 ), V3d( 1.0, 1.0, 1.0 ) ) ); } else { childBounds.set( Abc::Box3d() ); } a.getSchema().set( asamp ); } XformSample bsamp; for ( size_t i = 0 ; i < 20 ; ++i ) { bsamp.setInheritsXforms( (bool)(i&1) ); b.getSchema().set( bsamp ); } // for c we write nothing XformSample dsamp; dsamp.addOp( scaleop, V3d( 3.0, 6.0, 9.0 ) ); d.getSchema().set( dsamp ); XformSample esamp; M44d identmat; identmat.makeIdentity(); esamp.addOp( transop, V3d( 0.0, 0.0, 0.0 ) ); esamp.addOp( XformOp( kMatrixOperation, kMatrixHint ), identmat ); esamp.addOp( scaleop, V3d( 1.0, 1.0, 1.0 ) ); e.getSchema().set( esamp ); XformSample fsamp; fsamp.addOp( transop, V3d( 3.0, -4.0, 5.0 ) ); f.getSchema().set( fsamp ); // this will cause the Xform's values property to be an ArrayProperty, // since there will be 20 * 16 channels. XformSample gsamp; Abc::M44d gmatrix; gmatrix.makeIdentity(); for ( size_t i = 0 ; i < 20 ; ++i ) { gmatrix.x[0][1] = (double)i; gsamp.addOp( matrixop, gmatrix ); } g.getSchema().set( gsamp ); }
//-***************************************************************************** void sparseTest() { XformOp transOp( kTranslateOperation, kTranslateHint ); XformOp scaleOp( kScaleOperation, kScaleHint ); std::string nameA = "sparseXformTestA.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), nameA ); OXform transStatic( OObject( archive ), "transStatic" ); XformSample asamp; asamp.addOp( scaleOp, V3d( 2.0, 1.0, 2.0 ) ); transStatic.getSchema().set( asamp ); OXform transAnim( transStatic, "transAnim" ); XformSample bsamp; bsamp.addOp( transOp, V3d( 3.0, 4.0, 5.0 ) ); transAnim.getSchema().set( bsamp ); bsamp[0].setTranslate( V3d( 4.0, 5.0, 6.0 ) ); transAnim.getSchema().set( bsamp ); OXform identA( transAnim, "ident" ); OXform identB( identA, "ident" ); OXform transStatic2( identB, "transStatic" ); transStatic2.getSchema().set( asamp ); OXform transAnim2( transStatic2, "transAnim" ); transAnim2.getSchema().set( bsamp ); bsamp[0].setTranslate( V3d( 5.0, 6.0, 7.0 ) ); transAnim.getSchema().set( bsamp ); } std::string nameB = "sparseXformTestB.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), nameB ); // set this now as animated translate OXform transStatic( OObject( archive ), "transStatic", kSparse ); XformSample asamp; asamp.addOp( transOp, V3d( 1.0, 1.0, 1.0) ); transStatic.getSchema().set( asamp ); asamp[0].setTranslate( V3d( 2.0, 2.0, 2.0 ) ); transStatic.getSchema().set( asamp ); // this one will be static OXform transAnim( transStatic, "transAnim", kSparse ); XformSample bsamp; bsamp.addOp( scaleOp, V3d( 0.5, 0.5, 0.5 ) ); transAnim.getSchema().set( bsamp ); // from identity to static OXform identA( transAnim, "ident", kSparse ); identA.getSchema().set( bsamp ); // from identity to animated OXform identB( identA, "ident", kSparse ); identB.getSchema().set( asamp ); asamp[0].setTranslate( V3d( 3.0, 3.0, 3.0 ) ); identB.getSchema().set( asamp ); // don't set anything on these so they will be identity OXform transStatic2( identB, "transStatic", kSparse ); OXform transAnim2( transStatic2, "transAnim", kSparse ); } { std::vector< std::string > names; names.push_back( nameA ); names.push_back( nameB ); Alembic::AbcCoreFactory::IFactory factory; IArchive archive = factory.getArchive( names ); IXform transStatic( IObject( archive ), "transStatic" ); TESTING_ASSERT( !transStatic.getSchema().isConstantIdentity() ); TESTING_ASSERT( !transStatic.getSchema().isConstant() ); IXform transAnim( transStatic, "transAnim" ); TESTING_ASSERT( !transAnim.getSchema().isConstantIdentity() ); TESTING_ASSERT( transAnim.getSchema().isConstant() ); IXform identA( transAnim, "ident" ); TESTING_ASSERT( !identA.getSchema().isConstantIdentity() ); TESTING_ASSERT( identA.getSchema().isConstant() ); IXform identB( identA, "ident"); TESTING_ASSERT( !identB.getSchema().isConstantIdentity() ); TESTING_ASSERT( !identB.getSchema().isConstant() ); IXform transStatic2( identB, "transStatic" ); TESTING_ASSERT( transStatic2.getSchema().isConstantIdentity() ); IXform transAnim2( transStatic2, "transAnim" ); TESTING_ASSERT( transAnim2.getSchema().isConstantIdentity() ); } }
//-***************************************************************************** void someOpsXform() { std::string name = "someOpsXform.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), name ); OXform a( OObject( archive, kTop ), "a" ); OBox3dProperty bnds = CreateOArchiveBounds( archive ); XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformSample asamp; // scale asamp.addOp( scaleop, V3d( 2.0, 1.0, 2.0 ) ); // Maya-like shear XformOp shearmatrixop( kMatrixOperation, kMayaShearHint ); M44d shearmat; shearmat.makeIdentity(); asamp.addOp( shearmatrixop, shearmat ); // rotate x axis XformOp rotop( kRotateOperation, kRotateHint ); asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ), 1.57 ); // rotate y axis, angle will be animated asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ), 0.125 ); // rotate z axis, use a different hint for fun XformOp rotorientop( kRotateOperation, kRotateOrientationHint ); asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ), 0.1 ); // translate with animated y and z, different hint for fun XformOp transpivotop( kTranslateOperation, kRotatePivotPointHint ); asamp.addOp( transpivotop, V3d( 0.0, 0.0, 0.0 ) ); a.getSchema().set( asamp ); bnds.set( Box3d( V3d( -0.1, -0.1, -0.1 ), V3d( 0.1, 0.1, 0.1 ) ) ); for (size_t i = 1; i < 5 ; ++i) { asamp.addOp( scaleop, V3d( 2 * ( i + 1 ), 1.0, 2.0 ) ); shearmat.x[1][0] = (double)i; shearmat.x[2][0] = (double)( (int)i * -1.0 ); shearmat.x[2][1] = 0.0; asamp.addOp( shearmatrixop, shearmat ); asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ), 1.57 ); asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ), 0.125 * ( i + 1 ) ); asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ), 0.1 * ( i + 1 ) ); asamp.addOp( transpivotop, V3d( 0.0, 3.0 * i, 4.0 * i ) ); a.getSchema().set( asamp ); double iVal = static_cast< double >( i ); bnds.set( Box3d( V3d( -iVal, -iVal, -iVal ), V3d( iVal, iVal, iVal ) ) ); } } { IArchive archive( Alembic::AbcCoreOgawa::ReadArchive(), name ); IXform a( IObject( archive, kTop ), "a" ); IBox3dProperty bnds = GetIArchiveBounds( archive ); XformSample asamp; a.getSchema().get( asamp ); TESTING_ASSERT( a.getSchema().getNumOps() == 6 ); TESTING_ASSERT( asamp[0].isScaleOp() ); TESTING_ASSERT( asamp[0].getHint() == kScaleHint ); TESTING_ASSERT( asamp[1].isMatrixOp() ); TESTING_ASSERT( asamp[1].getHint() == kMayaShearHint ); TESTING_ASSERT( asamp[2].isRotateOp() ); TESTING_ASSERT( asamp[2].getHint() == kRotateHint ); TESTING_ASSERT( asamp[3].getType() == kRotateOperation ); TESTING_ASSERT( asamp[3].getHint() == kRotateHint ); TESTING_ASSERT( asamp[4].getType() == kRotateOperation ); TESTING_ASSERT( asamp[4].getHint() == kRotateOrientationHint ); TESTING_ASSERT( asamp[5].getType() == kTranslateOperation ); TESTING_ASSERT( asamp[5].getHint() == kRotatePivotPointHint ); TESTING_ASSERT( asamp[0].isXAnimated() ); TESTING_ASSERT( !asamp[0].isYAnimated() ); TESTING_ASSERT( !asamp[0].isZAnimated() ); TESTING_ASSERT( !asamp[1].isChannelAnimated(0) ); // [0][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(1) ); // [0][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(2) ); // [0][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(3) ); // [0][3] TESTING_ASSERT( asamp[1].isChannelAnimated(4) ); // [1][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(5) ); // [1][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(6) ); // [1][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(7) ); // [1][3] TESTING_ASSERT( asamp[1].isChannelAnimated(8) ); // [2][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(9) ); // [2][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(10) ); // [2][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(11) ); // [2][3] TESTING_ASSERT( !asamp[1].isChannelAnimated(12) ); // [3][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(13) ); // [3][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(14) ); // [3][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(15) ); // [3][3] TESTING_ASSERT( !asamp[2].isXAnimated() ); TESTING_ASSERT( !asamp[2].isYAnimated() ); TESTING_ASSERT( !asamp[2].isZAnimated() ); TESTING_ASSERT( !asamp[2].isAngleAnimated() ); TESTING_ASSERT( !asamp[3].isXAnimated() ); TESTING_ASSERT( !asamp[3].isYAnimated() ); TESTING_ASSERT( !asamp[3].isZAnimated() ); TESTING_ASSERT( asamp[3].isAngleAnimated() ); TESTING_ASSERT( !asamp[4].isXAnimated() ); TESTING_ASSERT( !asamp[4].isYAnimated() ); TESTING_ASSERT( !asamp[4].isZAnimated() ); TESTING_ASSERT( asamp[4].isAngleAnimated() ); TESTING_ASSERT( !asamp[5].isXAnimated() ); TESTING_ASSERT( asamp[5].isYAnimated() ); TESTING_ASSERT( asamp[5].isZAnimated() ); // OK, now check the values came through M44d shearmat; shearmat.makeIdentity(); TESTING_ASSERT( asamp[0].getScale() == V3d( 2.0, 1.0, 2.0 ) ); TESTING_ASSERT( asamp[1].getMatrix() == shearmat ); TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) ); TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[3].getAngle(), 0.125 ) ); TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) ); TESTING_ASSERT( almostEqual( asamp[4].getAngle(), 0.1 ) ); TESTING_ASSERT( asamp[5].getTranslate() == V3d( 0.0, 0.0, 0.0 ) ); TESTING_ASSERT( bnds.getValue() == Box3d( V3d( -0.1, -0.1, -0.1 ), V3d( 0.1, 0.1, 0.1 ) ) ); for ( index_t i = 1; i < 5 ; ++i ) { a.getSchema().get( asamp, ISampleSelector( i ) ); TESTING_ASSERT( asamp[0].getScale() == V3d( 2 * ( i + 1 ), 1.0, 2.0 ) ); shearmat.x[1][0] = (double)i; shearmat.x[2][0] = (double)( (int)i * -1.0 ); shearmat.x[2][1] = 0.0; TESTING_ASSERT( asamp[1].getMatrix() == shearmat ); TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) ); TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[3].getAngle(), 0.125 * ( i + 1 ) ) ); TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) ); TESTING_ASSERT( almostEqual( asamp[4].getAngle(), 0.1 * ( i + 1 ) ) ); V3d tvec( 0.0, 3.0 * i, 4.0 * i ); TESTING_ASSERT( tvec.equalWithAbsError( asamp[5].getTranslate(), VAL_EPSILON ) ); Box3d b = bnds.getValue( ISampleSelector( i ) ); double iVal = static_cast< double >( i ); TESTING_ASSERT( b == Box3d( V3d( -iVal, -iVal, -iVal ), V3d( iVal, iVal, iVal ) ) ); } std::cout << "tested all xforms in " << name << std::endl; } }
//-***************************************************************************** void xformIn() { IArchive archive( Alembic::AbcCoreOgawa::ReadArchive(), "Xform1.abc" ); Abc::M44d identity; XformSample xs; IXform a( IObject( archive, kTop ), "a" ); std::cout << "'a' num samples: " << a.getSchema().getNumSamples() << std::endl; TESTING_ASSERT( a.getSchema().getNumOps() == 1 ); TESTING_ASSERT( a.getSchema().getInheritsXforms() ); for ( index_t i = 0; i < 20; ++i ) { XformSample xs; a.getSchema().get( xs, Abc::ISampleSelector( i ) ); TESTING_ASSERT( xs.getNumOps() == 1 ); TESTING_ASSERT( xs[0].isTranslateOp() ); TESTING_ASSERT( xs[0].isYAnimated() == true ); TESTING_ASSERT( xs[0].isXAnimated() == false ); TESTING_ASSERT( xs[0].isZAnimated() == false ); TESTING_ASSERT( xs.getTranslation() == V3d( 12.0, i+42.0, 20.0 ) ); TESTING_ASSERT( xs.getMatrix() == Abc::M44d().setTranslation( V3d(12.0, i+42.0, 20.0)) ); } IXform b( a, "b" ); b.getSchema().get( xs ); TESTING_ASSERT( b.getSchema().getTimeSampling()->getTimeSamplingType().isUniform() ); // the schema is not static, because set() was called 20 times on it. TESTING_ASSERT( !b.getSchema().isConstant() ); TESTING_ASSERT( b.getSchema().getNumSamples() == 20 ); TESTING_ASSERT( xs.getNumOps() == 0 ); TESTING_ASSERT( b.getSchema().getNumOps() == 0 ); TESTING_ASSERT( xs.getMatrix() == identity ); for (size_t i = 0; i < 20; ++i) { AbcA::index_t j = i; TESTING_ASSERT( b.getSchema().getInheritsXforms( ISampleSelector( j ) ) == (i&1) ); } IXform c( b, "c" ); xs = c.getSchema().getValue(); TESTING_ASSERT( xs.getNumOps() == 0 ); TESTING_ASSERT( c.getSchema().getNumOps() == 0 ); TESTING_ASSERT( xs.getMatrix() == identity ); TESTING_ASSERT( c.getSchema().getInheritsXforms() ); TESTING_ASSERT( c.getSchema().isConstantIdentity() ); IXform d( c, "d" ); xs = d.getSchema().getValue(); TESTING_ASSERT( xs.getNumOps() == 1 ); TESTING_ASSERT( d.getSchema().getNumOps() == 1 ); TESTING_ASSERT( xs[0].isScaleOp() ); TESTING_ASSERT( ! ( xs[0].isXAnimated() || xs[0].isYAnimated() || xs[0].isZAnimated() ) ); TESTING_ASSERT( xs.getScale().equalWithAbsError( V3d( 3.0, 6.0, 9.0 ), VAL_EPSILON ) ); TESTING_ASSERT( xs.getMatrix() == Abc::M44d().setScale( V3d(3.0, 6.0, 9.0)) ); TESTING_ASSERT( d.getSchema().getInheritsXforms() ); IXform e( d, "e" ); TESTING_ASSERT( e.getSchema().isConstantIdentity() ); TESTING_ASSERT( e.getSchema().isConstant() ); TESTING_ASSERT( e.getSchema().getNumOps() == 3 ); IXform f( e, "f" ); TESTING_ASSERT( f.getSchema().isConstant() ); // is constant TESTING_ASSERT( ! f.getSchema().isConstantIdentity() ); // not identity IXform g( f, "g" ); Abc::M44d gmatrix; gmatrix.makeIdentity(); XformSample gsamp = g.getSchema().getValue(); TESTING_ASSERT( gsamp.getNumOps() == 20 ); TESTING_ASSERT( gsamp.getNumOpChannels() == 20 * 16 ); TESTING_ASSERT( g.getSchema().getNumSamples() == 1 ); TESTING_ASSERT( g.getSchema().isConstant() ); TESTING_ASSERT( !g.getSchema().isConstantIdentity() ); for ( size_t i = 0 ; i < 20 ; ++i ) { TESTING_ASSERT( gsamp[i].getChannelValue( 1 ) == (double)i ); } std::cout << "Tested all xforms in first test!" << std::endl; }