Source/Architecture/Alembic

= Alembic =

Export
The exporter follows these broad steps:


 * 1) Create Time Samples: when exporting more than one frame, Blender constructs two lists of frame numbers to export (one for transforms, and one for shapes), converts from frame numbers to samples, and passes them to the Alembic library. There can be more than one "time sampling", for example when transforms are subsampled 10x per frame, but mesh shapes only 1x per frame.
 * 2) Construct Writer Objects: the objects in the scene are inspected and writer objects are created in the correct hierarchy.
 * 3) Write Data: for every sample in the list of time stamples, the correct frame is set and the writer objects are called upon to write their data.

Minimal Exporter Code Example
The Alembic library is using C++ object references to manage the writing of data. This means that when a variable in C++ goes out of scope, the object is finalized and can no longer be written to or even obtained from the Alembic library. This is different from the USD library, where USD objects can always be obtained by their path in the USD Stage.

Writing data consists of a few steps:


 * 1) Add the object by creating the correct C++ variable. This can be `OXForm transform` or `OPolyMesh mesh`. This is what defines the type of object in Alembic. The constructor also receives the name in Alembic, the parent object, and the index of the time sampling to be used for this object.
 * 2) Get the Schema by creating another C++ variable. The schema is what defines the avaiable properties in the Alembic object, and how to convert them to C++ values. Examples are `  OXformSchema` and `OPolyMeshSchema`. In the above examples you create those by simpling calling `transform.getSchema` or `mesh.getSchema`. The schema holds a reference to its owning object, so to prevent the Alembic library from finalizing the object you only have to keep a reference to either the schema or the object itself.
 * 3) Write the Sample by creating another C++ variable of the right type, setting its properties, and calling `the_schema.set(the_sample)`. This sample variable can be recreated for every frame or reused, here it's not important to keep a reference around. Calling the schema's `set` function magically forwards the time sample index for the object. This is why in Blender's exporter you won't find a call to tell Alembic the current frame/time. This time sample index is maintained per object.

Here is an example file that writes an animated transform: