How to add new meta data to alembic file in maya?

1.1k Views Asked by At

I want to add some extra information into the exists abc file or if its possible while creating alembic cache with some extra information in maya or any cg application using pyhon. I am appreciate any one can help me to edit the alembic file.

input example

meta_data = {'name': 'Hero', 'tag': 'test_show'}
abc_file = '/show/test_show/scene/hero.abc'

set meta data ?

from alembic import Abc

get meta data

from alembic import Abc

archive = Abc.IArchive(abc_file)
top = archive.getTop()
meta_data = top.getMetaData()
print meta_data__str()
2

There are 2 best solutions below

8
ababak On BEST ANSWER

You can't write just arbitrary data but you can set description and application strings:

from alembic import Abc

MY_APP = 'My cool application'


def write(abc_file, description):
    archive = Abc.CreateArchiveWithInfo(abc_file, MY_APP, description) 

def read(abc_file):
    archive = Abc.IArchive(abc_file)
    top = archive.getTop()
    return Abc.GetArchiveInfo(archive)

abc_file = 'alembic.abc'
write(abc_file, 'An abc file cool description')
archive_info = read(abc_file)
print(archive_info.get('appName'))
print(archive_info.get('userDescription'))
print(archive_info.get('whenWritten'))
1
ababak On

Here's a complete script that does the job of copying the source alembic file and inserting some metadata:


import os
import alembic


def copy_props(i_props, o_props):
    '''
    Copy properties
    '''
    for index in range(i_props.getNumProperties()):
        header = i_props.getPropertyHeader(index)
        if header.isArray():
            i_prop = alembic.Abc.IArrayProperty(
                i_props,
                header.getName())
            prop_name = i_prop.getName()
            prop_meta = i_prop.getMetaData()
            o_prop = alembic.Abc.OArrayProperty(
                o_props,
                prop_name,
                i_prop.getDataType(),
                prop_meta,
                0)
            o_prop.setTimeSampling(i_prop.getTimeSampling())
            for i in range(i_prop.getNumSamples()):
                o_prop.setValue(i_prop.getValue(i))
        elif header.isScalar():
            i_prop = alembic.Abc.IScalarProperty(
                i_props,
                header.getName())
            prop_name = i_prop.getName()
            prop_meta = i_prop.getMetaData()
            o_prop = alembic.Abc.OScalarProperty(
                o_props,
                prop_name,
                i_prop.getDataType(),
                prop_meta,
                0)
            o_prop.setTimeSampling(i_prop.getTimeSampling())
            for i in range(i_prop.getNumSamples()):
                o_prop.setValue(i_prop.getValue(i))
        elif header.isCompound():
            i_prop = alembic.Abc.ICompoundProperty(
                i_props,
                header.getName())
            prop_name = i_prop.getName()
            prop_meta = i_prop.getMetaData()
            o_prop = alembic.Abc.OCompoundProperty(
                o_props,
                prop_name,
                prop_meta)
            copy_props(i_prop, o_prop)


def copy_object(i_obj, o_obj):
    '''
    Recursively copy object data
    '''
    if o_obj is None:
        return
    i_props = i_obj.getProperties()
    o_props = o_obj.getProperties()
    copy_props(i_props, o_props)
    for index in range(i_obj.getNumChildren()):
        i_child = i_obj.getChild(index)
        i_child_name = i_child.getName()
        i_child_meta = i_child.getMetaData()
        o_child = alembic.Abc.OObject(o_obj, i_child_name, i_child_meta)
        copy_object(i_child, o_child)


def copy_abc(i_path, o_path, app, description):
    '''
    Copy alembic file from i_path to o_path
    '''
    arc_in = alembic.Abc.IArchive(i_path)
    arc_out = alembic.Abc.OArchive(o_path, asOgawa=True)
    arc_out = alembic.Abc.CreateArchiveWithInfo(o_path, app, description)
    top_in = arc_in.getTop()
    top_out = arc_out.getTop()
    copy_object(top_in, top_out)


def read(abc_file):
    archive = alembic.Abc.IArchive(abc_file)
    return alembic.Abc.GetArchiveInfo(archive)


if __name__ == '__main__':
    i_path = os.path.join(
        os.path.dirname(__file__),
        'itest.abc'
    )
    o_path = os.path.join(
        os.path.dirname(__file__),
        'otest.abc'
    )
    copy_abc(i_path, o_path, 'Cool app', 'Cool description')
    print('Created archive: ' + o_path)
    archive_info = read(o_path)
    print('App name: ' + archive_info.get('appName'))
    print('Description: ' + archive_info.get('userDescription'))
    print('Written: ' + archive_info.get('whenWritten'))