The 3ds Max file format, not too much documentation to be found about it. There are some hints here and there about how it's built up, but there exists no central documentation on it.

Right now we are in the following situation. A few thousand of max files, created by a very old version of max (3.x), containing path references to textures and other max files that have been renamed and relocated or which simply no longer exist. Yes, we have a maxscript that can go through them all, and that manages to fix a large number of paths. However, there are a lot of paths that are stored as part as fields in plugins and material scripts that don't get noticed, and the performance of opening and closing this number of files from 3ds Max directly is horrible. The obvious solution? Figure out how we can read and save the max file with modified contents, without having to understand all of the actual data it contains. Fortunately, this is actually possible without too much work.

Some research online brings up the following blog post, relating to a change in the max file format in version 2010, which would make it easier to update asset paths: http://www.the-area.com/blogs/chris/reading_and_modifying_asset_file_paths_in_the_3ds_max_file. That's nice and all, but it's only from version 2010 on, and it very likely won't contain any assets referenced by path by old plugins and such.

So, starting at the beginning. The blog post I referred to above nicely hints us to the OLE structured file format. Since there exist a wide range of implementations for that, we can pretty much skip that, and accept that it's basically a filesystem in a file, so it's a file containing multiple file streams. A reliable open source implementation of this container format can be found in libgsf. When scanning a fairly recent max file, using the command gsf list, we can find the following streams inside this file:

f         52 VideoPostQueue
f 147230 Scene
f 366 FileAssetMetaData2
f 2198 DllDirectory
f 29605 Config
f 3438 ClassDirectory3
f 691 ClassData
f 29576 SummaryInformation
f 2320 DocumentSummaryInformation

The FileAssetMetaData2 is new in 3ds Max 2010.

One step further, we can start examining the contents of these streams. And it's usually easiest to start off with one of the more simple ones. VideoPostQueue seems small enough to figure out the overall logic of the file format, hoping that the rest is serialized in a similar way. Using the command gsf dump we can get a hex output of one of the streams, and using a simple text editor we can find how it's structured. Binary formats often contain 32 bit length values, which are usually easy to spot in small files, since they'll contain a large number of 00 values. It's basically a matter of finding possible 32bit length integers, and matching them together with various fixed length fields and other typical binary file contents, until something programatically logical turns up. Here's a manually parsed VideoPostQueue storage stream:

[
50 00 (id: 0x0050)
0a 00 00 00 (size: 10 - 6 = 4)
[
01 00 00 00 (value: 1)
]
]
[
60 00 (id: 0x0060)
2a 00 00 80 (size: 42 - 6 = 36) (note: negative bit = container)
[
10 00 (id: 0x0010)
1e 00 00 00 (size: 30 - 6 = 24)
[
07 00 00 00 (value: 7)
01 00 00 00 (value: 1)
00 00 00 00
00 00 00 00
20 12 00 00 (value: 4610)
00 00 00 00
]
20 00 (id: 0x0020)
06 00 00 00 (size: 6 - 6 = 0)
]
]

The storage streams in the max container file contain a fairly simple chunk based file format (and in fact similar in format to the fairly well known .3ds file format). Being based on chunks is what allows 3ds Max to open a file for which certain plugins are missing. It's basically a tree structured format where every entry has an identifier and a size, so when an identifier is unknown, or when it's contents are incompatible, it can simply be kept as is or discarded. The only exceptions in the file that don't use this structure are SummaryInformation and DocumentSummaryInformation, which are supposedly in a standard Windows format, and the new FileAssetMetaData2 section is formatted differently as well unfortunately.

In this format, the chunk header consists of a 2-byte unsigned integer which is the identifier, and a 4-byte unsigned integer, where the 31 least significant bits are the size and the msb is a flag that helpfully lets us know if the chunk itself contains more chunks, and thus is a container, or not. For very large files, where 31 bits is insufficient for the size, the entire size field is set to 0, and the header increases with an additional 64-bit unsigned integer field which is similarly structured as the 32-bit size field. The size field includes the size of the header.

       0 | 0f 20 (id)
00 00 00 00 (size missing)
17 fe 01 00 00 00 00 80 (size in 64 bits)

With this information it is possible to read a max file, modify the binary contents of chunks (most of them are fairly basic of format), and we should be able to re-save the max file with our modified data. The DllDirectory section, for example, parsed programatically starts like this:

CStorageContainer - items: 20
[0x21C0] CStorageValue - bytes: 4
786432216
[0x2038] CStorageContainer - items: 2
[0x2039] CStorageUCString - length: 39
Viewport Manager for DirectX (Autodesk)
[0x2037] CStorageUCString - length: 19
ViewportManager.gup
[0x2038] CStorageContainer - items: 2
[0x2039] CStorageUCString - length: 49
mental ray: Material Custom Attributes (Autodesk)
[0x2037] CStorageUCString - length: 21
mrMaterialAttribs.gup
[0x2038] CStorageContainer - items: 2
[0x2039] CStorageUCString - length: 37
Custom Attribute Container (Autodesk)
[0x2037] CStorageUCString - length: 23
CustAttribContainer.dlo
...

Of course, it would be interesting if we could go further, and directly manipulate the parameters of our own plugins and scripts from our own tools back into the max files so that everything is centrally stored without any duplicate source data in the way. And that's exactly what I'll be doing next.

【转】http://blog.kaetemi.be/post/2012/08/17/3ds-Max-File-Format-%28Part-1%29

3ds Max File Format (Part 1: The outer file format; OLE2)的更多相关文章

  1. 3ds Max File Format (Part 5: How it all links together; ReferenceMaker, INode)

    At this point, you should start to familiarize yourself a bit with the publicly available 3ds Max AP ...

  2. [iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ格式分析

    [iTyran原创]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ文件格式分析作者:yuezang - iTyran     在iOS的3D开发中常常需要导入通过3DS MAX之类 ...

  3. AVEVA PDMS to 3ds Max - RvmTranslator6.0beta

    AVEVA PDMS to 3ds Max - RvmTranslator6.0beta eryar@163.com RvmTranslato6.0 translate PDMS RVM to 3ds ...

  4. VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人]

    VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人] 对最新版本的V ...

  5. 万圣节福利:红孩儿3D引擎开发课程《3ds max导出插件初步》

    ds max文件夹,插件文件夹以及3ds max的可执行程序文件夹: 位的,这里要改成x64,否则启动程序后3ds max会提示"不是有效的win32程序"之类的对话框. 然后要将 ...

  6. 【Unity】3.3 用3ds Max 2015制作模型并将其导入到Unity

    分类:Unity.C#.VS2015 创建日期:2016-04-05 一.常用三维软件简介 由于游戏引擎本身的建模功能相对较弱,无论是专业性还是自由度都无法同专业的三维软件相比,所以大多数游戏中的模型 ...

  7. 3ds Max从入门到精通

    1. 软件的下载与安装 这里用的是3ds Max2009简体中文版 32位 在 Win7上运行记得打上sp2补丁,不然会有bug. 2. 3ds Max的历史 3ds Max可以用在动画和游戏,点云数 ...

  8. 3DS MAX玩家必看!70个提高渲染速度的小技巧

    3DS MAX玩家必看!70个提高渲染速度的小技巧 (注:节省RAM不一定会加快渲染速度.请同学们根据实际情况加以利用.) 1. 尽量限制Ploygon数量,越少渲染速度越快 2. 如果使用Vray, ...

  9. (转)Unity与3ds Max的单位关系(使用FBX文件)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/a1780531/article/deta ...

随机推荐

  1. #《Essential C++》读书笔记# 第五章 面向对象编程风格

    基础知识 继承机制定义了父子(parent/child)关系.父类(parent)定义了所有子类(children)共通的共有接口(public interface)和私有实现(private imp ...

  2. NIO学习笔记,从Linux IO演化模型到Netty—— Linux零拷贝

    这里只是感性地认识Linux零拷贝,不涉及具体细节. 1.Linux传统的数据拷贝 用户进程是不能直接访问文件系统的,要先切换到内核态,发起系统调用,DMA把磁盘中的数据写入内核空间,内核再把数据拷贝 ...

  3. python3的bytes数据类型

    python已升级到了3.0,都说现在是属于python3,未来也是属于python3,那python3到底改了些什么呢? 其中我记得非常清楚的是,python3对文本和二进制数据作了更为清晰的区分. ...

  4. AOV拓扑排序实验-2-AOV类的实现

    下面是这个类的实现代码: //这只是一个基本的框架,没有封装 #include<iostream> #include<cstdio> #include<malloc.h& ...

  5. MySQL 8 服务端帮助支持

    MySQL 服务器支持 HELP 语句,该语句返回参考手册中相应信息,比如: mysql> help change master to; 返回创建主从复制相关语句的信息 参考手册的信息存储在my ...

  6. mongodb 基础入门教程

    算是学习下来精炼的笔记,希望对大家有帮助.如果有问题欢迎大家指正. 0.概述 MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统. 在高负载的情况下,添加更多的节点,可以保 ...

  7. 2019牛客多校第二场H题(悬线法)

    把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...

  8. List<SelectListItem> 转为 SelectList

    List<SelectListItem> 转为/转换 SelectList SelectList slPayCh = new SelectList(GetPayChannels(),&qu ...

  9. 每天进步一点点------Modelsim添加Xilinx仿真库的详细步骤

    Modelsim,可以选型SE和XE两个版本.Modelsim XE可以直接被ISE调用,而Modelsim SE需要手动添加仿真库.但SE版和OEM版在功能和性能方面有较大差别,比如对于大家都关心的 ...

  10. 0级搭建类002-Oracle Linux 8.x安装(OEL 8.0) 公开

    项目文档引子系列是根据项目原型,制作的测试实验文档,目的是为了提升项目过程中的实际动手能力,打造精品文档AskScuti. 项目文档引子系列目前不对外发布,仅作为博客记录.如学员在实际工作过程中需提前 ...