[译]3D应用程序和软件之间2D形状的快速互操作性
By robot-v1.0
本文链接 https://www.kyfws.com/applications/fast-interoperability-of-d-shapes-between-d-applic-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 9 分钟阅读 - 4039 个词 阅读量 0[译]3D应用程序和软件之间2D形状的快速互操作性
原文地址:https://www.codeproject.com/Articles/41959/Fast-Interoperability-of-D-Shapes-between-D-Applic
原文作者:Inaki Ayucar
译文由本站 robot-v1.0 翻译
前言
Fast interoperability of 2D shapes between 3D applications and your software
3D应用程序和软件之间2D形状的快速互操作性
前言(Preface)
维基百科(Wikipedia) 说互操作性是(says that interoperability is)**“一种财产,指的是不同的系统和组织协同工作(互操作)的能力”.(“a property referring to the ability of diverse systems and organizations to work together (inter-operate)”.)关于软件,它说互操作性是(Regarding software, it says that interoperability is)“不同程序通过一组通用的交换格式交换数据的能力”.(“the capability of different programs to exchange data via a common set of exchange formats”.)**这一直是个问题,特别是在谈论管理3D或2D信息的软件时,由于要交换的信息量和多样性,这一直是一个问题.(This has always been a problem, especially when talking about software that manages 3D or 2D information, due to the volume and diversity of the information to be exchanged.)
为什么这是一个问题?(Why is That a Problem?)
例如,在2D图像中,人们始终或多或少地清楚了应用程序应该共享哪种信息:2D颜色表,以一种或另一种格式表示,但毕竟是颜色或光量.有一些"事实上的"标准,例如(In 2D images, for instance, it has always been more or less clear what kind of information applications should share: 2D tables of colors, expressed in one format or another, but color or amount of light, after all. There are some ‘de-facto’ standards like) TGA(TGA) (来自IBM)和其他机构或委员会开发的其他文件,例如JPEG(名称来自((coming from IBM) and others developed by institutions or committees, like JPEG (name coming from) 联合摄影专家组(Joint Photographic Experts Group) ).某些格式尝试包含其他信息,例如不透明度(alpha通道),或以其他形式表示相同的信息,例如所谓的HDR(高动态范围)图像,该图像需要将照明信息存储在浮点中.(). Some formats try to include other information, like opacity (alpha channels), or to express the same information in other forms, like the so-called HDR (High Dynamic Range) images, which need to store lighting information in floating point.)
3D是一个完全不同的故事.主要是因为虽然2D成像是一个成熟的领域(也是相对简单的领域),但是3D可视化仍在逐月变化,其新技术和算法需要将新的复杂信息存储在文件中.除此之外,还有几种3D应用程序,它们也有不同的需求:3D建模程序包,实时应用程序,视频游戏等.所有这些使互操作性成为一个难题,并且可以从两个不同的应用程序共享场景一场噩梦,参数无法识别,信息丢失等.(3D is a completely different story. Mostly because while 2D imaging is a mature field (and a relatively simple one too), 3D visualization is still changing a lot form month to month, with new techniques and algorithms, that need new and complex information stored in files. In addition to that, there are several kind of 3D applications, with different needs too: 3D modeling packages, real-time applications, videogames, etc. All this stuff makes interoperability a hard issue, and sharing a scene from two different applications can be a nightmare, with un-recognized parameters, missing information, etc.)
但是,尽管有上面写的内容,但已经进行了许多尝试以使某些文件格式成为标准.是旧的情况(However, and despite the written above, there have been many tries to become certain file formats a standard. It is the case of the old) 3DS(3DS) (来自AutoDesk),X文件格式(来自Microsoft –DirectX-)或更高版本((from AutoDesk), the X File Format (from Microsoft –DirectX-), or the newer) FBX(FBX) ,这是AutoDesk尝试建立标准3D文件格式的最新尝试,并且受到以下方面的支持(, which is the latest try from AutoDesk to build a standard 3D file format, and is also supported by) XNA(XNA) .(.)
2D Shapes案例(The 2D Shapes Case)
看起来似乎很明显,但是3D格式非常关注3D,而2D形状经常被分开.例如,3DS或默认FBX文件格式都不支持2D形状.这就是一个问题,因为样条线等2D形状对于我们软件中的许多功能非常有用:动画,人工智能等的路径或轨迹.(It may seem something obvious, but 3D formats are very focused in 3D, and 2D shapes are frequently left apart. For instance, neither 3DS or the default FBX file formats support 2D shapes. And that’s a problem, as 2D shapes like splines are very useful for many things in our software: paths or trajectories for animation, A.I., etc.)
有什么解决方案?(What’s the Solution?)
实际上,有许多解决方案:(In fact, there are many solutions:)
- 使用支持2D形状的其他文件格式(Use a different file format that supports 2D shapes)
- 使用FBX SDK制作自己的出口商/进口商(Use the FBX SDK to make your own exporters/importers)
- 将2D形状导出为3D对象(例如,当使用3DS文件格式时,这就是3DSMax所做的事情).(Export 2D shapes as 3D objects (this is what 3DSMax does when using the 3DS file format, for instance).)
- 等等(etc.) 我猜最好的选择是第二个:使用FBX格式,这似乎是下一个标准,并且在其中包含对2D形状的支持之前,请自己创建出口商.但是,这需要我们很多人,要学习使用SDK的方法,并在此周围为不同的3D建模包制作导出器和导入器.您应该采用这种方式,但是如果您没有足够的时间,我将在这里为您展示使用现有文件格式的更简单解决方案.(I guess the best option would be the second one: use the FBX format, which seems to be the next standard, and until support for 2D shapes is included on it, make your own exporters/importers. However, that would take quite a bunch of ours, learning to use the SDK, and making exporters and importers for the different 3D modeling packages round there. You should go this way, but if you do not have time enough, I´ll show you an easier solution here, using an existing file format.)
选择正确的文件格式(Choosing the Proper File Format)
有几种支持2D形状的文件格式,但并非全部都是开放格式.在3D建模应用程序通常支持的几种格式中,我们找到了两种"大多数为开放式"格式:ASE文件格式(ASCII)和(There are several file formats which support 2D shapes, but not all of them are Open Formats. Among the usually supported by 3D modeling applications, we find two “mostly open” formats: the ASE file format (ASCII) and the) OBJ文件格式(OBJ file format) ,由WaveFront开发.他们俩都会做到,但我们将选择第二个((, developed by WaveFront. Both of them would make it, but we will choose the second ()OBJ(OBJ)),因为第一个比较复杂,并且默认情况下3DSMax不包括ASE导入器(仅与导出器一起提供).() because the first one is a bit more complex, and because 3DSMax does not include an ASE importer by default (it comes with an exporter only).)
OBJ分析器(仅2D形状)(The OBJ Parser (2D Shapes Only))
请注意(Please note):我在这里不会写完整的OBJ格式的解析器.我们将只包含几行代码来读取OBJ文件,其中包含2D样条曲线的信息.(: I won’t write here a full parser of the OBJ format. We will just include a few lines of code to read OBJ files which hold information of 2D splines.)
以下类将读取OBJ文件中存在的每个2D形状,并将顶点列表存储在(The following class will read each 2D shape present in the OBJ file, and store the list of vertices in a) Dictionary
(按形状名称键入).请注意,我刚刚使用从3DS Max导出的OBJ文件(仅存储2D样条线)测试了此代码.您可以进行自己的测试,并根据需要更改代码.呼吁"((keyed by the name of the shape). Please note that I have just tested this code with OBJ files exported from 3DS Max, storing 2D splines only. You can make your own tests and change the code as necessary. A call to “) LoadFile
“将填充”(” will fill the “) mFoundSplines
“,其中包含文件中找到的形状信息.(” collection with the information of the shapes found in the file.)
注意(Note):某些3D应用程序,例如(: Some 3D applications, like) 3DSMax
,将轴坐标与”(, use axis coordinates with the “) Z
“指向"上”,而其他人则喜欢与"(” pointing “up”, while others prefer coordinates with the “) Y
朝上.就我而言,第二个选项是默认选项,因此如果您愿意(” pointing up. In my case, this second option is the default, so if you want) Z
指向(从/读取或保存文件)(to point up (to read or save files from/to) 3DSMax
),则应将参数设置为"(), you should set the parameter “) pSwapYZ
" 至(” to) true
在打电话给(in the call to) LoadFile
.(.)
public class OBJFileParser
{
public static Dictionary<string, DX.Vector3[]> mFoundSplines;
private static System.IO.StreamReader mStrmReader;
/// <summary>
///
/// </summary>
public static void LoadFile(string pFullFileName, bool pSwapYZ)
{
try
{
mFoundSplines = new Dictionary<string, Microsoft.DirectX.Vector3[]>();
mStrmReader = new System.IO.StreamReader(pFullFileName);
while (!mStrmReader.EndOfStream)
{
string line = mStrmReader.ReadLine();
if (line.StartsWith("# shape"))
{
string[] parts = line.Split(' ');
if (parts.Length != 3)
continue;
ReadShape(parts[2], pSwapYZ);
}
}
}
finally { mStrmReader.Close(); }
}
/// <summary>
///
/// </summary>
private static void ReadShape(string pShapeName, bool pSwapYZ)
{
List<DX.Vector3> vertices = new List<Microsoft.DirectX.Vector3>();
while (!mStrmReader.EndOfStream)
{
string line = mStrmReader.ReadLine();
// Skip lines starting with #
if (line.StartsWith("#"))
continue;
// Read Vertex
if (line.StartsWith("v"))
{
// Important !: There are two spaces (‘ ‘) between the
// "v" and the first component of the vector. Split will return 5
// strings
string[] parts = line.Split(' ');
if (parts.Length != 5)
continue;
if(pSwapYZ)
vertices.Add(new Microsoft.DirectX.Vector3
(float.Parse(parts[2]), float.Parse(parts[4]), float.Parse(parts[3])));
else vertices.Add(new Microsoft.DirectX.Vector3
(float.Parse(parts[2]), float.Parse(parts[3]), float.Parse(parts[4])));
}
// Shapes have a line starting with "g" (plus the name of the shape),
// and another one with what seems to be indices to vertices.
// In this case, we won´t read that info, so we will use the
// "g"-starting line to detect the end of a shape
if (line.StartsWith("g"))
break;
}
// Add Spline
if (vertices.Count > 0)
mFoundSplines.Add(pShapeName, vertices.ToArray());
}
}
OBJ保护程序(仅2D形状)(The OBJ Saver (2D Shapes Only))
现在,我们将按照OBJ格式保存样条线,并确保3DS Max能够读取它.要使用它,您需要像这样调用每个方法:(We will save now our Splines following the OBJ format, and making sure that 3DS Max is able to read it. To use it, you need to call each method like:)
OBJFileSaver.StartNewFile()
:重置内部集合(: To reset internal collections)OBJFileSaver.AddShape()
:添加要保存的每个形状(: To add each shape you want to save)OBJFileSaver.SaveFile()
:最后将所有内容保存到磁盘.(: To finally save everything to disk.) 注意:(Note:)一些3D应用程序,例如(Some 3D applications, like)3DSMax
,将轴坐标与"(, use axis coordinates with the “)Z
“指向"上”,而其他人则喜欢与"(” pointing “up”, while others prefer coordinates with the “)Y
朝上.就我而言,第二个选项是默认选项,因此如果您愿意(” pointing up. In my case, this second option is the default, so if you want)Z
指向(从/读取或保存文件)(to point up (to read or save files from/to)3DSMax
),则应将参数设置为"(), you should set the parameter “)pSwapYZ
" 至(” to)true
在打电话给(in the call to)SaveFile
.(.)
public class OBJFileSaver
{
private static System.IO.StreamWriter mStrmWriter = null;
private static Dictionary<string, DX.Vector3[]> mShapes;
/// <summary>
///
/// </summary>
/// <param name="pFullFileName"></param>
public static void StartNewFile()
{
mShapes = new Dictionary<string, Microsoft.DirectX.Vector3[]>();
}
/// <summary>
///
/// </summary>
/// <param name="?"></param>
/// <param name="pShape"></param>
public static void AddShape(string pShapeName, DX.Vector3[] pShape)
{
mShapes.Add(pShapeName, pShape);
}
/// <summary>
///
/// </summary>
public static void SaveFile(string pFullFileName, bool pSwapYZ)
{
try
{
mStrmWriter = new System.IO.StreamWriter(pFullFileName);
int vertexIdx = 1;
foreach (string name in mShapes.Keys)
{
WriteShape(name, vertexIdx, pSwapYZ);
vertexIdx += mShapes[name].Length;
}
}
finally
{
mStrmWriter.Close();
}
}
/// <summary>
///
/// </summary>
/// <param name="pName"></param>
private static void WriteShape(string pShapeName, int pVertexStartIdx, bool pSwapYZ)
{
// Write header
mStrmWriter.WriteLine("");
mStrmWriter.WriteLine("#");
mStrmWriter.WriteLine("# shape " + pShapeName);
mStrmWriter.WriteLine("#");
mStrmWriter.WriteLine("");
// Write vertices. Important !!: Set two (2) spaces between "v" and X component of vertex.
foreach (DX.Vector3 vec in mShapes[pShapeName])
{
if(pSwapYZ)
mStrmWriter.WriteLine(string.Format("v {0} {1} {2}", vec.X, vec.Z, vec.Y));
else mStrmWriter.WriteLine(string.Format("v {0} {1} {2}", vec.X, vec.Y, vec.Z));
}
// Write number of vertices
mStrmWriter.WriteLine("# " + mShapes[pShapeName].Length + " vertices");
mStrmWriter.WriteLine("");
// Write the "g" line, with the name of the shape again
mStrmWriter.WriteLine("g " + pShapeName);
// Write what seems to be a trivial list of indices to vertices.
// It doesn´t re-start for each shape
string indices = "l ";
int vertexIdx = pVertexStartIdx;
for (int i = 0; i < mShapes[pShapeName].Length; i++)
{
indices += vertexIdx + " ";
vertexIdx++;
}
mStrmWriter.WriteLine(indices);
mStrmWriter.WriteLine("");
mStrmWriter.Flush();
}
}
本类的局限性(Limitations of This Class)
请记住,此类将仅导出样条曲线的输出几何形状(仅导出顶点位置)和形状名称.不包括其他参数,如花键张力,连续性,切线等.关于3DSMax或任何其他建模应用程序的任何其他信息(例如插值属性)也不会保存.(Keep in mind that this class will only export the output geometry of your Splines (only vertex positions) and the name of the shape. Other parameters like Spline tension, continuity, tangents, etc. are not included. Any other information regarding 3DSMax or any other modeling application (like interpolation properties) will not be saved either.)
结论(Conclusion)
在诸如FBX之类的更多标准格式支持2D形状之前(这很快就会发生),这是向您的应用程序添加对2D形状的支持的一种非常简单的方法.希望你觉得它有用 !(Until more standard formats like FBX support 2D shapes (something that should happen soon), this is a very easy way to add support for 2D shapes to your applications. Hope you find it useful !)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# 新闻 翻译