Mesh数据结构解析

多边形 (polygon) 在Maya内部是如何处理的


多边形 (polygon) mesh 是由基本数据结构的组件(面、边、顶点)组成的。 这个数据结构被封装在一个多边形 (polygon) mesh 节点中, 以保证在 Maya 的核心构架--依赖关系图 中提供结构。这些概念对于在Maya中操作和与多边形交互至关重要。

译者注: 这节是废话,无法理解可以不看


多边形 (polygon) 的组件

多边形网格(polygon mesh)由三种基本组件组成:

1. 顶点 (Vertices)

2. 边   (Edges)

3. 面   (Faces)


除了这三个基本的多边形组件外,还有两个额外的组件,同样在理解如何在 Maya 中处理多边形(polygon)时非常重要:

1. 面-顶点 (Face-Vertices)

2. UV坐标  (UVs)


顶点  (Vertices)


   Vertex
 


多边形网格(polygon mesh)的顶点(Vertices)存储在一个简单的3D浮点点数组中,每个点都有基于数组中给定索引的顶点ID。后续讲到的边和面都基于此数组。


   Vertex
 


译者注: 这里的 X Y Z 就是每个顶点的 X Y Z 轴的坐标。可以理解为这样的概念:


Mesh.vtx = [ [ X1, Y1, Z1], [X2, Y2, Z2], ... [Xn, Yn, Zn] ]


边 (Edges)


   Edge
 


多边形网格(polygon mesh)的边(Edges)也存储在一个数组中(边数组 Edge array)。边数组中的每条边都由两个整数组成,这个整数就是顶点(Vertex)的编号(ID)。第一个整数(Vertex ID)表示边的起始顶点,而第二个整数(Vertex ID)表示边的结束顶点。这为边提供了顶点组合、方向和边ID(由边数组的索引表示)。


   Edge
 


译者注: 值得注意的是使用数组记录边的起始点到结束点,不仅描述的边的形状位置,还描述的边的方向。这很重要

可以理解为这样的概念:


Mesh.e = [ [A1, B1], [A2, B2], ... [An, Bn] ]

# 加上上面的点的概念, 我们可以假设一种结构

Mesh.vtx = [ [ X1, Y1, Z1], [X2, Y2, Z2], ... [Xn, Yn, Zn] ]

Mesh.e = [ [Mesh.vtx[0], Mesh.vtx[1] ], ... [ Mesh.vtx[-2], Mesh.vtx[-1] ] ]


面 (Faces)


多边形网格(polygon mesh)的面(Face)存储在一个整数数组中。每个面由一系列整数序列描述,序列内部的每个整数都是一条边的ID。第一个边序列描述面的外边界,任何后续序列表示面中可能存在孔洞。我们用内部标记来记录每个面所有序列的开始和结束,这便是面的描述。


   Face
 


译者注:这里的图例和原文档中的图例略有不同,为了更好的理解这里的概念,我重新设计了这张图例。

可能和官方文档想要表述的不完全相符,但是有利于理解概念。图中所显示的面的组成在工作中是需要极力避免的,因为这会带来一些问题,这种结构在Maya中可以正常实现,但是在其他DCC软件中可能并不行,而且大多数数据交换格式都不支持这种模型结构的承载。请确保你的面内部孔洞和外部边界的边是相连的。大多数据交换格式在储存模型时只储存面的顶点顺序。


Mesh.Face = [ [ (edge3, edge4, edge5) , (edge0, edge1, edge2) ], [ (edge3, edge4, ...) , (...) ], ... ]


这里介绍另外一种更加通用的记录面数据的一种方法,使用一个整数数组, 数组内的每一个单元全部由顶点(Vertex)构成。顶点的顺序决定了面的结构,这种结构不支持凭空在面中打孔的操作。


   Faces
 


Mesh.Face = [[vtx0, vtx1, vtx2], [vtx3, vtx4, ...], ...]


面偏移和索引数组补充了面数组。该数组保存了面数组中每个面描述的起始位置。由于每个面可以由多个边序列以及多个顶点序列组成,因此遍历数组以查找每个面的开头可能是比较麻烦的事情。这个面索引数组提供了快速访问有关每个面的信息的方法。我们将面ID作为面偏移数组的引索ID。除了标记每个面的开始的元素之外,还会在面索引数组的末尾附加一个元素,以标记面列表中的最后一个索引。这个最后的索引数字允许您快速访问每个面的顺序(面中的边数/顶点数)。


   Face
 


译者注:这里的图例和原文档中的图例略有不同,为了更好的理解这里的概念,我重新设计了这张图例。正如上方两个小节所说的。边Offset 实际上是一个引索,可以快速的知道指定的面(ID)所构成的顶点有哪些。这个对于几何计算是非常重要的。


图中,ID 为 0 的面偏移(Offset)值为0,此时需要查询它的顶点数量以及顶点组成。根据下一个面 ID + 1 的引索值可知该面的顶点查询的Index范围是 0 - 3 , 顶点数为 4 个。 并且是由 0, 1, 3, 2 组成的。 这样如果这个模型面数非常大的话,就不需要遍历一整个模型了。


Mesh.FaceOffset = [0, 4, 8, 12]

Mesh.FaceVertex = [0, 1, 3, 2, 1, 0, 4, 5, 1, 5, 7, 6, 0, 2, 9, 8]



face_range = [Mesh.FaceOffset[ID], Mesh.FaceOffset[ID+1]]

face_count = face_range[1] - face_range[0] + 1

face_vertex = Mesh.FaceVertex[face_range[0]:face_range[1]]


面-顶点 (Face-Vertices)


在面相邻的情况下,面经常会共用顶点。有时我们会需要将数据关联到特定面的特定顶点,同时将该特定顶点与共享它的任何面区分开来。这些称为 面-顶点(Face-Vertices)。


面-顶点(Face-Vertices) 是一种多边形的概念性组件,其概念可以使用于 —例如— 每个顶点的颜色或者UV坐标。面-顶点(Face-Vertices) 由现有的数据结构表示——面数组和面索引数组。每个面-顶点(Face-Vertices)与特定的面ID和顶点ID相关联。您可以使用面ID在面数组中找到偏移量,然后通过使用每个边的起始顶点在边循环中搜索给定的顶点ID。请注意,每个面中的每个顶点ID都是给定面-顶点(Face-Vertices)的唯一索引——面-顶点(Face-Vertices)索引。共享的顶点ID在面数组中会多次出现,在共享该顶点的每个面描述中都会出现一次。


   Face
 


现在假设我们将其用于UV坐标

在上面的插图中,左图描绘了一个由四个面组成的多边形平面的拓扑结构,而右图展示了该四个面多边形平面的面顶点视图。在面顶点视图中,每个面都是分开的,保持着自己独立的顶点。每个独立的顶点都使用相对于每个面的顶点索引进行标记(即从0到3)。每个面顶点与一个UV相关联。然而,这并不保证每个面顶点都有唯一的UV。默认情况下,对于代表共享顶点的面顶点,比如左图中的顶点4,每个面顶点与相同的UV相关联,因此共享一个UV。将UV进行“分割”会为每个共享顶点的面顶点提供一个唯一的UV ID。


译者注:这里的图例和原文档中的图例略有不同,为了更好的理解这里的概念,我重新设计了这张图例。Face-Vertex 实际上应该是一种抽象的概念。

可以理解为一种模板概念,在MAYA中UV和顶点着色均使用了这个概念来安排数据。图中的 UV ID 并不代表了真实情况下的 UV ID 排列方式,这里只是便于理解。


Mesh.Face = [ [0, 1, 4, 3], [ 1, 2, 5, 4], ... [] ]

Face-Vertex = (0  1  2  3)  ( 0  1  2  3)  ...



UV坐标 (UVs)


UV坐标在很大程度上依赖于面-顶点(Face-Vertices)的概念。UV坐标对应于一个二维平面,用于将纹理映射到多边形表面上。纹理映射是逐个面进行的。因此,为了允许每个面具有自己的一组映射坐标,UV坐标是基于面-顶点(Face-Vertices)的。在Maya中,保存UV坐标的结构由两个数组组成:


1. 一个UV索引数组,它使用与面数组完全相同的索引(可以视为 面-顶点(Face-Vertices) 数组)。

2. 一个UV数组,它保存由 UV ID 索引的UV点列表。


第一个数组将每个面顶点与特定的 UV ID 关联起来,如果面顶点所属的面没有进行映射,则不进行关联。每个 UV ID 对应于 UV 列表中的一个索引,该索引保存了 UV 在 UV 空间中所处的二维坐标(U和V浮点值)。


   UV
 


译者注:这里的图例和原文档中的图例略有不同,为了更好的理解这里的概念,我重新设计了这张图例。正如上方两个小节所说的。一个顶点实际上由于被多个面共享,所以实际上在拆分UV时,是可以拆分为多个UV点的,图中就演示了这个现象 点1 由于被两个面共享。所以在将这两个面的UV拆分时, 可以拆分为两个UV点


   UV
 


如这个图所示:UV 点 3 的顶点由 两个面共享, 但是,由于这两个面没有拆分,所以 UV 点 3 也还是由这两个面共享。 UV 点 7 和 9 实际拥有同一个 顶点,但是这里我们将UV经行了拆分。 所以分配了 新的 UV ID 给它们。


## Mesh结构总结

mesh 的基本数据上可由以下的代码获取


# 这里举一个正方体Mesh的例子

mesh_object = pm.PyNode("pCube1")



mesh_object.vtx[x].getPosition()

P0 = [-0.5, -0.5,  0.5]

P1 = [ 0.5, -0.5,  0.5]

P2 = [-0.5,  0.5,  0.5]

P3 = [ 0.5,  0.5,  0.5]

P4 = [-0.5,  0.5, -0.5]

P5 = [ 0.5,  0.5, -0.5]

P6 = [-0.5, -0.5, -0.5]

P7 = [ 0.5, -0.5, -0.5]



def get_face_offset():

    face_offsets = [0]

    for face in mesh_object.f:

        per_face_vertex = len(face.connectedVertices())

        face_offsets.append(face_offsets[-1] + per_face_vertex)

face_offset = (0, 4, 8, 12, 16, 20, 24)



mesh_object.getVertices()

vertex_array = [0, 1, 3, 2, 2, 3, 5, 4, 4, 5, 7, 6,

                6, 7, 1, 0, 1, 7, 5, 3, 6, 0, 2, 4]   # vertex ID



mesh_object.getUVs()

U_array = [0.375, 0.625, 0.375, 0.625, 0.375, 0.625, 0.375, 0.625, 0.375, 0.625, 0.875, 0.875, 0.125, 0.125]

V_array = [0.0,   0.0,   0.25,  0.25,  0.5,   0.5,   0.75,  0.75,  1.0,   1.0,   0.0,   0.25,  0.0,   0.25]


免责声明:本文系网络转载或改编,未找到原创作者,版权归原作者所有。如涉及版权,请联系删

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空