Search code examples
python3dexportmayaalembic

Python, Alembic.io, Cask: Properties of object do not save when using write_to_file()


I am often writing scripts for various 3d packages (3ds max, Maya, etc) and that is why I am interested with Alembic, a file format that is getting a lot of attention lately.

Quick explanation for anyone who does not know this project: alembic - www.alembic.io - is a file format created for containing 3d meshes and data connected with them. It is using a tree-like structure, as You may see below, with one root node and its childs, childs of childs etc. Objects of this node can have properties.

I am trying to learn how to use this Alembic with Python.

There are some tutorials on docks page of this project and I'm having some problems with this one: http://docs.alembic.io/python/cask.html It's about using cask module - a wrapper that should manipulating a content of files easier.

This part:

a = cask.Archive("animatedcube.abc")
r = cask.Xform()
x = a.top.children["cube1"]
a.top.children["root"] = r
r.children["cube1"] = x
a.write_to_file("/var/tmp/cask_insert_node.abc")

works well. Afther that there's new file "cask_insert_node.abc" and it has objects as expected.

But when I'm adding some properties to objects, like this:

a = cask.Archive("animatedcube.abc")
r = cask.Xform()
x = a.top.children["cube1"]
x.properties['new_property'] = cask.Property()
a.top.children["root"] = r
r.children["cube1"] = x
a.write_to_file("/var/tmp/cask_insert_node.abc")

the "cube1" object in a resulting file do not contain property "new_property". The saving process is a problem, i know that the property has been added to "cube1" before saving, I've checked it another way, with a function that I wrote which creates graph of objects in archive.

The code for this module is there: source

Does anyone know what I am doing wrong? How to save parameters? Some other way?


Solution

  • Sadly, cask doesn't support this. One cannot modify an archive and have the result saved (somehow related to how Alembic streams the data off of disk). What you'll want to do is create an output archive

    oArchive = alembic.Abc.CreateArchiveWithInfo(...)
    

    then copy all desired data from your input archive over to your output archive including time sampling (

    .addTimeSampling(iArchive.getTimeSampling(i) for i in iArchive.getNumTimeSamplings()
    

    , and objects, recursing through iArchive.getTop() and oArchive.getTop() defining output properties (alembic.Abc.OArrayProperty, or OScalarProperty) as you encounter them in the iArchive. When these are defined, you can interject your new values as samples to the property at that time.

    It's a real beast, and something that cask really ought to support. In fact, someone in the Alembic community should just do everyone a favor and write a cask2 (casket?) which wraps all of this into simple calls like you instinctively tried to do.