//-*****************************************************************************
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 );
        }
    }
}
Esempio n. 3
0
//-*****************************************************************************
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 );
    }
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
//-*****************************************************************************
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 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;
    }
}