[3D数据存储] Archive (File Container) | 创建/写入/读取 | 存储格式HDF5
链接:https://www.alembic.io/
docs:Alembic
Alembic是一种强大的开放交换格式和库,用于高效存储和交换复杂3D场景数据。
它允许艺术家和工作室以稳健无损的方式在不同3D软件应用之间**归档和传输动画几何体、相机及材质**。
概览
章节
- 归档(文件容器)
- 对象(场景节点)
- 属性(数据容器)
- 时间采样(动画时间轴)
- 几何体模式(3D数据类型)
- 材质模式(着色器定义)
- 分层归档(文件叠加)
第一章:归档(文件容器)
欢迎进入Alembic的精彩世界~
在这开篇章节中,我们将从Alembic存储3D数据的基础——归档(常称为文件容器)开始探索。
什么是归档?为什么需要它?
想象我们正在创建复杂3D场景,可能包含:
- 角色模型
- 角色动画(行走、跳跃)
- 背景环境(树木、山脉)
- 场景照明
- 捕捉动作的相机
传统方式保存这些元素意味着需要多个文件
,或依赖特定软件专属格式。这使得协作共享变得困难。
Alembic通过将所有3D场景相关元素打包至单一自包含文件解决此问题,该文件即称为"归档"(或文件容器)。
可将Alembic归档视作特殊.zip
文件,但专为3D图形数据设计。
它不仅压缩文档,更以高度结构化方式高效存储3D模型、动画、相机等元素。
本章目标是掌握Alembic归档基础操作:打开现有归档读取数据与创建新归档写入数据。
读取归档数据(IArchive
)
当需要处理现有Alembic文件(如my_scene.abc
)时,需"打开"它。Alembic中使用IArchive
(“I"代表"输入"或"读取”)。
由于Alembic文件可能采用不同底层格式(如HDF5或Ogawa,目前无需深究),Alembic提供名为IFactory
的智能工具识别文件格式。IFactory
如同智能"钥匙串",尝试不同密钥直至找到正确方式打开文件。
以下是C++中使用IFactory
打开Alembic文件的示例:
#include <Alembic/AbcCoreFactory/All.h> // 用于IFactory
#include <Alembic/Abc/All.h> // 用于IArchive// ... 函数内部 ...Alembic::AbcCoreFactory::IFactory factory; // 智能钥匙串
Alembic::AbcCoreFactory::IFactory::CoreType coreType; // 识别文件类型// 尝试打开"input_scene.abc"
Alembic::Abc::IArchive archive = factory.getArchive("input_scene.abc", coreType);// 验证归档是否成功打开
if (!archive.valid())
{// 错误处理:文件无法打开printf("错误:指定的Alembic文件无效!\n");return 1; // 返回失败状态
}// 执行至此,'archive'已代表打开的Alembic文件~
factory.getArchive
若"input_scene.abc"有效,archive
变量将成为有效IArchive
对象,作为访问文件内3D数据的入口。
写入归档数据(OArchive
)
创建新Alembic文件并保存3D场景时,使用OArchive
(“O"代表"输出"或"写入”)。
创建OArchive
时需指定存储格式,主流选项为HDF5
和Ogawa
,初学者任选其一即可,选择通常取决于性能需求。
以下是使用HDF5格式创建"output_scene.abc"的示例:
#include <Alembic/AbcCoreHDF5/All.h> // 用于HDF5写入
#include <Alembic/Abc/All.h> // 用于OArchive// ... 函数内部 ...// 创建名为"output_scene.abc"的新Alembic文件
// 使用Alembic::AbcCoreHDF5::WriteArchive()指定HDF5格式Alembic::Abc::OArchive outArchive = Alembic::Abc::OArchive(Alembic::AbcCoreHDF5::WriteArchive(), // 指定使用HDF5"output_scene.abc", // 新文件名Alembic::Abc::MetaData(), // 可选:当前为空元数据Alembic::Abc::ErrorHandler::kThrowPolicy // 错误处理策略
);// 执行至此,'outArchive'已代表新建的空Alembic文件~
此代码将创建"output_scene.abc"文件,初始为空,outArchive
对象已准备好接收3D场景元素。
数据存储格式
HDF5
一种通用的文件格式,用于存储和管理大规模科学数据,支持分层组织和高效压缩,广泛应用于科研和工程领域。
Ogawa
Alembic(一种3D图形数据交换格式)的专用存储格式,针对动画和特效数据的快速读写进行了优化,结构简单且轻量。
底层原理:归档工作机制
简析打开/创建Alembic归档时的内部过程。
打开归档(IArchive
)
IFactory
打开Alembic文件的过程:
- 用户请求:告知
IFactory
要打开的文件名 - 文件检查:
IFactory
读取文件头确定内部结构(如HDF5、Ogawa) - 阅读器创建:根据文件类型创建对应阅读器(如
AbcCoreOgawa::ReadArchive
) IArchive
就绪:返回IArchive
对象供访问数据
Alembic工具AbcConvert
演示此过程,可见factory.getArchive
调用:
// 摘自:bin/AbcConvert/AbcConvert.cpp
// ...
Alembic::AbcCoreFactory::IFactory factory;
Alembic::AbcCoreFactory::IFactory::CoreType coreType;// 单个输入文件时直接获取归档
if(options.inFiles.size() == 1)
{archive = factory.getArchive(*options.inFiles.begin(), coreType);// ... 错误处理 ...
}
// ...
factory.getArchive
尝试打开文件并识别coreType
,archive
变量即成为IArchive
实例。
IArchive
类定义于lib/Alembic/Abc/IArchive.h
,其构造函数接收ARCHIVE_CTOR
(由IFactory
在识别文件类型后提供):
// 摘自:lib/Alembic/Abc/IArchive.h
// ...
template <class ARCHIVE_CTOR>
IArchive::IArchive( ARCHIVE_CTOR iCtor, // 特定阅读器(HDF5、Ogawa)const std::string &iFileName,ErrorHandler::Policy iPolicy,AbcA::ReadArraySampleCachePtr iCachePtr )
{// ...m_archive = iCtor( iFileName, iCachePtr ); // 实际打开文件// ...
}
// ...
创建归档(OArchive
)
创建新Alembic文件过程更直接,因需明确指定格式:
- 用户请求:指定文件名和存储格式(如
Alembic::AbcCoreHDF5::WriteArchive()
) - 容器初始化:
OArchive
在磁盘创建空文件并写入格式头信息 OArchive
就绪:返回OArchive
对象作为新文件句柄
AbcConvert.cpp
示例展示如何显式创建OArchive
:
// 摘自:bin/AbcConvert/AbcConvert.cpp
// ...
Alembic::Abc::OArchive outArchive;
if (options.toType == IFactoryNS::kHDF5)
{outArchive = Alembic::Abc::OArchive(Alembic::AbcCoreHDF5::WriteArchive(), // 指定HDF5写入器options.outFile, // 输出文件名inTop.getMetaData(), // 元数据(从输入复制)Alembic::Abc::ErrorHandler::kThrowPolicy);
}
// ...
此处直接使用Alembic::AbcCoreHDF5::WriteArchive()
作为ARCHIVE_CTOR
创建HDF5格式输出归档。
OArchive
类定义于lib/Alembic/Abc/OArchive.h
,其构造函数模式相同:
// 摘自:lib/Alembic/Abc/OArchive.h
// ...
template <class ARCHIVE_CTOR>
OArchive::OArchive( ARCHIVE_CTOR iCtor, // 特定写入器(HDF5、Ogawa)const std::string &iFileName,const Argument &iArg0,const Argument &iArg1 )
{// ...m_archive = iCtor( iFileName, args.getMetaData() ); // 实际创建文件// ...
}
// ...
总结
本章学习到**Alembic归档**是3D场景数据的核心容器,如同专用压缩文件。
- 使用
IArchive
**读取**现有Alembic文件,常借助IFactory
自动检测文件格式 - 使用
OArchive
**写入**新Alembic文件,明确选择存储格式(如HDF5或Ogawa)
IArchive
和OArchive
是操作这些强大数据容器的主要接口。但容器内具体结构如何?这正是下一章要探索的内容!
第二章:对象(场景节点)