本文介绍使用Maya Python实现“根据UV复制模型顶点位置”和“根据模型顶点ID复制模型顶点位置”两种功能。并演示一种巧妙的UV修改方法,能够快速的在不改变模型的情况下复制相同拓扑模型的UV。
一、根据UV复制模型顶点
首先,我们准备两个UV相同,顶点位置不同的模型。如图一所示:

我们想要将左侧的baseMesh的顶点位置修改为右侧tarMesh的顶点位置,可以使用“传递属性”功能,位置在“建模-网格-传递变量”中,点击右侧的小方格就会弹出传递属性的选项框,可以手动选择要传递的属性和采样空间(传递属性的依据)。如图二所示:

图二中我们要传递的属性为顶点位置,采样空间为UV,而我们准备的这两个模型的UV完全一致,因此在绝大多数情况下都能保证模型的顶点位置正确传递(有很小概率传递失败)。
操作顺序:
1、选择tarMesh(目标模型)
2、加选baseMesh(要修改的模型),加选按Shift
3、点击传递属性按钮
可以看到,baseMesh的顶点位置已经跟tarMesh完全一致了。值得注意的是,顶点位置指的是模型的中心枢轴与各个顶点的相对位置,与世界坐标无关。

或者,可以使用MayaPython进行快速修改,属性依次为:目标模型,要修改的模型,是否修改顶点位置=1,是否修改法线=0,是否修改UV=0,是否修改颜色=0,采样空间=3(0是世界空间,1是模型空间,3是基于UV的,4是基于点序的,5是基于拓扑的),是否UV反转=0,是否混合颜色边框=1,指定关联点时要使用的搜索方法=3最靠近点。
可以在 Help 中自行查看更多细节
cmds.transferAttributes("tarMesh", "baseMesh",
transferPositions=1, transferNormals=0,
transferUVs=0, transferColors=0,
sampleSpace=3,flipUVs=0,
colorBorders=1, searchMethod=3)
在Maya中运行以上代码也能实现图三的效果。
二、根据模型顶点ID复制模型顶点位置
如果能确定你准备的两个模型的顶点除位置以外是完全一致的,包括顶点数量,顶点ID和顺序。那么可以使用BS来将想要修改的模型顶点位置修改到目标顶点位置,并且只需要两行代码即可:
cmds.blendShape("tarMesh", "baseMesh", weight=(0, 1.0))
# 删除历史
cmds.delete("baseMesh", constructionHistory=True)
该代码可以在baseMesh中创建一个变形为tarMesh的BS,并且将权重值改成1,达到根据模型顶点ID复制模型顶点位置的效果。值得注意的是,此方法会在模型上添加一个节点,因此,最好使用“删除历史”功能将模型清理干净再做后续操作。
三、复制相同拓扑模型的UV
由于笔者再Maya Python中没有找到直接的复制相同拓扑模型UV的代码,因此想到了一种取巧的方法来解决这个问题。
先来介绍一下使用场景。如下两图所示,由于种种原因,我们的模型已经调整好需要的顶点位置,但UV出现了错误,且无法撤销还原。我们需要在保留右侧模型顶点位置的情况下将左侧模型的UV复制给右侧模型。
注意:两个模型的拓扑一致。


具体思路为:不去复制UV,而是复制顶点位置,将左侧模型baseMesh的顶点位置修改为右侧的模型顶点位置即可。
1、复制左侧模型baseMesh,命名为:dupMesh
2、为dupMesh 创建一个能够形变为右侧模型tarMesh的BS
3、清除dupMesh 的历史
4、删除右侧模型tarMesh
5、将dupMesh 的名字重命名为右侧模型tarMesh
baseMesh = "baseMesh"
tarMesh = "tarMesh"
# 1、复制
dupMesh = cmds.duplicate(baseMesh )[0]
# 2、为dupMesh创建一个能够形变为右侧模型tarMesh的BS
cmds.blendShape(tarMesh , dupMesh , weight=(0, 1.0))
# 3、清除dupMesh的历史
cmds.delete(dupMesh , constructionHistory=True)
# 4、删除右侧模型tarMesh
cmds.delete(tarMesh )
# 5、将dupMesh 的名字重命名为右侧模型tarMesh
cmds.rename(dupMesh , tarMesh )

这个方法有点鸠占鹊巢的意思。
共勉。