MY BLOG DIRECTORY:YivanLee:专题概述及目录zhuanlan.zhihu.com
INTRODUCTION:
上一卷花了三小时入门了Maya python脚本编程,这一部分主要是在Maya中用脚本做一些功能,这些一个个的功能经过封装和UI制作就能成插件。
MAIN CONTENT:
【1】在模型顶点上再生成模型
import maya.cmds as cmd
vertexes = cmd.ls(selection = True, fl = True)
for vet in vertexes:
pos = cmd.xform(vet, query = True, translation = True, worldSpace = True)
print pos
ball = cmd.polySphere(sx = 10, sy = 10, r = 0.5, name = str(vet))
cmd.move(pos[0],pos[1], pos[2], ball)
【2】给模型设置随机顶点色
操作之前需要打开顶点色预览
import maya.cmds as cmd
import random
random.seed(1234)
vertexes = cmd.ls(selection = True, fl = True)
for vet in vertexes:
cmd.select('%s' % vet)
r = random.uniform(0, 1)
g = random.uniform(0, 1)
b = random.uniform(0, 1)
cmds.polyColorPerVertex(rgb=(r, g, b))
【3】把世界坐标烘焙到定点色里
import maya.cmds as cmd
import random
random.seed(1234)
vertexes = cmd.ls(selection = True, fl = True)
for vet in vertexes:
cmd.select('%s' % vet)
pos = cmd.xform(vet, query = True, translation = True, worldSpace = True)
r = pos[0]
g = pos[1]
b = pos[2]
cmds.polyColorPerVertex(rgb=(r, g, b))
【4】获取模型法线,并运算,并把它存到顶点色里作为第二套法线
import maya.cmds as cmd
vertexes = cmd.ls(selection = True, fl = True)
for vet in vertexes:
cmd.select('%s' % vet)
normal = cmd.polyNormalPerVertex(query = True, xyz = True)
r = normal[0] * 2 - 1
g = normal[1] * 2 - 1
b = normal[2] * 2 - 1
cmds.polyColorPerVertex(rgb=(r, g, b))
【5】修改顶点法线
import maya.cmds as cmd
vertexes = cmd.ls(selection = True, fl = True)
for vet in vertexes:
cmd.select('%s' % vet)
normal = cmd.polyNormalPerVertex(xyz = (0,1,0))
【6】碰撞检测
从 om.MFloatPoint(0, 10, 0)处,沿-Y发射射线,得到一个位置,并且在这个位置上生成Locator
import maya.cmds as cmds
import maya.OpenMaya as om
def Tracing():
pos = om.MPoint()
dir = om.MVector()
hitpoint = om.MFloatPoint()
allMeshInScene = cmds.ls(type='mesh')
startPoint = om.MFloatPoint(0, 10, 0)
rayDir = om.MFloatVector(0, -1, 0)
for mesh in allMeshInScene:
selectionList = om.MSelectionList()
selectionList.add(mesh)
dagPath = om.MDagPath()
selectionList.getDagPath(0, dagPath)
fnMesh = om.MFnMesh(dagPath)
intersection = fnMesh.closestIntersection(
om.MFloatPoint(startPoint),
om.MFloatVector(rayDir),
None,
None,
False,
om.MSpace.kWorld,
99999,
False,
None,
hitpoint,
None,
None,
None,
None,
None)
if intersection:
x = hitpoint.x
y = hitpoint.y
z = hitpoint.z
cmds.spaceLocator(p = (x,y,z))
Tracing()
【7】在模型表面点击生成Locator
import maya.OpenMaya as om
import maya.OpenMayaUI as omui
import maya.cmds as cmds
ctx = 'myCtx'
def onPress():
vpX, vpY, _ = cmds.draggerContext(ctx, query=True, anchorPoint=True)
print(vpX, vpY)
pos = om.MPoint()
dir = om.MVector()
hitpoint = om.MFloatPoint()
omui.M3dView().active3dView().viewToWorld(int(vpX), int(vpY), pos, dir)
pos2 = om.MFloatPoint(pos.x, pos.y, pos.z)
for mesh in cmds.ls(type='mesh'):
selectionList = om.MSelectionList()
selectionList.add(mesh)
dagPath = om.MDagPath()
selectionList.getDagPath(0, dagPath)
fnMesh = om.MFnMesh(dagPath)
intersection = fnMesh.closestIntersection(
om.MFloatPoint(pos2),
om.MFloatVector(dir),
None,
None,
False,
om.MSpace.kWorld,
99999,
False,
None,
hitpoint,
None,
None,
None,
None,
None)
if intersection:
x = hitpoint.x
y = hitpoint.y
z = hitpoint.z
cmds.spaceLocator(p = (x,y,z))
if cmds.draggerContext(ctx, exists = True):
cmds.deleteUI(ctx)
cmds.draggerContext(ctx, pressCommand = onPress, name = ctx, cursor = 'crossHair')
cmds.setToolTo(ctx)
这里制作了一个工具并绑定到工具架上
这个工具的PressCommand绑定到了我们脚本的Press函数。
【8】在maya python脚本中把数组数据存到贴图里并导出
import maya.OpenMaya as op
m_util = op.MScriptUtil
m_height = 64
m_width = 64
m_depth = 4
m_image = OpenMaya.MImage()
m_image.create(m_height, m_width, m_depth)
m_pixels = m_image.pixels()
m_arrayLen = m_width * m_height * m_depth
for i in range(0, m_arrayLen, m_depth):
m_util.setUcharArray(m_pixels, i+0, 255)
m_util.setUcharArray(m_pixels, i+1, 255)
m_util.setUcharArray(m_pixels, i+2, 0)
m_util.setUcharArray(m_pixels, i+3, 0)
m_image.setPixels(m_pixels, m_height, m_width)
m_image.writeToFile( "F:/Test.png", '.png' )
这里其实只要改一下后缀名就能导出各种图片格式了,OpenMaya.Image这个类十分强大。
【9】在ObjectMode下选中一个物体,直接对其UV进行修改
import maya.cmds as cmd
SelectMeshList = cmd.ls(selection = True, flatten = True)
if len(SelectMeshList) > 0:
MeshToModify = SelectMeshList[0]
MeshUVArray = cmd.ls("{}.map[0:]".format(MeshToModify), flatten = True)
for UV in MeshUVArray:
cmd.select(UV)
cmd.polyEditUV(scaleU = 2)
cmd.select(clear = True)
SUMMARY AND OUTLOOK:
先这样吧,以后还有觉得不错的小功能代码我会在这篇文章里补。第三卷也就是下一卷是做大插件。我写Python的时候还是喜欢c++的驼峰写法,各种flag的缩写真心无法接受,比如:
cmd.ls(s = 1, f = 1)
这是什么,正统应该这么写!
cmd.ls(selection = True, flatten = True)
每次看代码都要反应半天想这个缩写全称是啥,这真是写时一时爽,维护火葬场。
enjoy it.
NEXT: