You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Maya Python API为单个网格的各UV壳设置随机顶点颜色

为多UV壳网格高效分配随机顶点颜色(Maya Python API实现)

问题背景

当单个网格包含多个UV壳时,需要为每个UV壳分配随机顶点颜色。此前基于cmds的实现在高密度网格下运行速度极慢,现需通过Maya Python API实现高效方案。

当前尝试的代码

import maya.api.OpenMaya as om2
import random

def setColors():

    shells = getUvShelList( cmds.ls(sl=1)[0] )

    print ( shells )

    """
    #3 similar objects combined into one
    {0: ['pCube4.map[0]', 'pCube4.map[1]', 'pCube4.map[2]', 'pCube4.map[3]', 'pCube4.map[4]', 'pCube4.map[5]', 'pCube4.map[6]', 'pCube4.map[7]', 'pCube4.map[8]', 'pCube4.map[9]', 'pCube4.map[10]', 'pCube4.map[11]', 'pCube4.map[12]', 'pCube4.map[13]'], 
    1: ['pCube4.map[14]', 'pCube4.map[15]', 'pCube4.map[16]', 'pCube4.map[17]', 'pCube4.map[18]', 'pCube4.map[19]', 'pCube4.map[20]', 'pCube4.map[21]', 'pCube4.map[22]', 'pCube4.map[23]', 'pCube4.map[24]', 'pCube4.map[25]', 'pCube4.map[26]', 'pCube4.map[27]'], 
    2: ['pCube4.map[28]', 'pCube4.map[29]', 'pCube4.map[30]', 'pCube4.map[31]', 'pCube4.map[32]', 'pCube4.map[33]', 'pCube4.map[34]', 'pCube4.map[35]', 'pCube4.map[36]', 'pCube4.map[37]', 'pCube4.map[38]', 'pCube4.map[39]', 'pCube4.map[40]', 'pCube4.map[41]']}
    """
    
    selList2 = om2.MGlobal.getActiveSelectionList()
    dagPath = selList2.getDagPath(0)
    selMesh = om2.MFnMesh(dagPath)
    
    vertList = list(set(selMesh.getVertices()[1]))
    lenVertList = len(vertList)
    
    for shell in shells:
        selection_shell = shells.get(shell)

        r = [random.random() for i in range(3)]
        tempColor = om2.MColor([r[0],r[1],r[2]])
        vertexColorList = om2.MColorArray(lenVertList, tempColor)
        
        selMesh.setVertexColors(vertexColorList, vertList) 

setColors()

此前慢速的cmds实现

for shell in chunk:
    selection_shell = shells.get(shell)
    
    cmds.select(selection_shell)
    facesSel = cmds.polyListComponentConversion(fromUV=True, toFace=True)
    cmds.select(facesSel)
    r = [random.random() for i in range(3)]
    cmds.polyColorPerVertex(facesSel,rgb=(r[0], r[1], r[2]), cdo=1 )
    
    cmds.select(deselect=1)

高效实现方案

当前尝试的代码存在两个核心问题:一是每次循环都会覆盖所有顶点的颜色,最终只有最后一个UV壳的颜色生效;二是多次调用setVertexColors导致API开销过大。以下是优化后的实现:

优化代码

import maya.api.OpenMaya as om2
import random

def get_uv_shell_vertices(mesh_dag, uv_components):
    """从UV壳的UV组件列表中提取对应的顶点ID(自动去重)"""
    mesh_fn = om2.MFnMesh(mesh_dag)
    vertex_ids = set()
    
    for uv_comp in uv_components:
        # 解析UV组件字符串,提取UV索引
        uv_index = int(uv_comp.split('[')[-1].rstrip(']'))
        # 获取该UV关联的所有顶点
        _, vert_ids = mesh_fn.getAssociatedFacesAndVerticesForUV(uv_index)
        vertex_ids.update(vert_ids)
    
    return list(vertex_ids)

def setColors():
    # 获取选中的网格对象
    sel_list = om2.MGlobal.getActiveSelectionList()
    if sel_list.length() == 0:
        om2.MGlobal.displayError("请选择一个网格对象")
        return
    
    dag_path = sel_list.getDagPath(0)
    mesh_fn = om2.MFnMesh(dag_path)
    mesh_name = om2.MFnDagNode(dag_path).name()
    
    # 获取UV壳列表(假设getUvShelList已实现,返回{壳ID: [UV组件列表]})
    shells = getUvShelList(mesh_name)
    if not shells:
        om2.MGlobal.displayWarning("未检测到UV壳")
        return
    
    # 获取网格所有顶点ID,初始化颜色数组
    all_vertex_ids = list(set(mesh_fn.getVertices()[1]))
    color_array = om2.MColorArray(len(all_vertex_ids), om2.MColor([0, 0, 0]))
    
    # 为每个UV壳分配随机颜色
    for _, uv_components in shells.items():
        shell_verts = get_uv_shell_vertices(dag_path, uv_components)
        # 生成随机RGB颜色
        rand_color = om2.MColor([random.random(), random.random(), random.random()])
        # 更新颜色数组中对应顶点的颜色
        for vid in shell_verts:
            color_array[vid] = rand_color
    
    # 一次性设置所有顶点颜色,大幅降低API调用开销
    mesh_fn.setVertexColors(color_array, all_vertex_ids)
    om2.MGlobal.displayInfo("顶点颜色分配完成")

setColors()

优化说明

  • 减少API调用:仅调用一次setVertexColors完成所有顶点颜色设置,避免多次调用的开销
  • 避免颜色覆盖:通过预初始化颜色数组,逐个更新对应UV壳顶点的颜色,确保每个壳的颜色都能保留
  • 高效顶点映射:直接通过Maya API获取UV关联的顶点,避免cmds选择、组件转换等冗余操作
  • 自动去重:用集合存储顶点ID,避免重复设置同一顶点的颜色

内容的提问来源于stack exchange,提问作者johancc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 03:25:48